Full Code of florent37/AndroidUnitTest for AI

master 9f6e63d6cb5e cached
63 files
87.3 KB
21.8k tokens
159 symbols
1 requests
Download .txt
Repository: florent37/AndroidUnitTest
Branch: master
Commit: 9f6e63d6cb5e
Files: 63
Total size: 87.3 KB

Directory structure:
gitextract_jyd7hg8s/

├── .gitignore
├── LICENSE
├── README.md
├── androidunittest/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── github/
│       │               └── florent37/
│       │                   └── androidunittest/
│       │                       └── ApplicationTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── github/
│       │   │           └── florent37/
│       │   │               └── androidunittest/
│       │   │                   ├── AndroidUnitTest.java
│       │   │                   ├── AndroidUnitTestAnnotations.java
│       │   │                   ├── AndroidUnitTestRunner.java
│       │   │                   ├── annotations/
│       │   │                   │   ├── RActivity.java
│       │   │                   │   ├── RContext.java
│       │   │                   │   ├── RFragment.java
│       │   │                   │   └── RView.java
│       │   │                   ├── controllers/
│       │   │                   │   ├── ControllerActivity.java
│       │   │                   │   └── ControllerFragment.java
│       │   │                   ├── managers/
│       │   │                   │   ├── AbstractAnnotationManager.java
│       │   │                   │   ├── AnnotationActivityManager.java
│       │   │                   │   ├── AnnotationContextManager.java
│       │   │                   │   ├── AnnotationFragmentManager.java
│       │   │                   │   └── AnnotationViewManager.java
│       │   │                   └── states/
│       │   │                       └── ActivityState.java
│       │   └── res/
│       │       └── values/
│       │           └── strings.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── github/
│                       └── florent37/
│                           └── androidunittest/
│                               └── managers/
│                                   ├── AnnotationActivityManagerTest.java
│                                   ├── AnnotationContextManagerTest.java
│                                   ├── AnnotationFragmentManagerTest.java
│                                   └── AnnotationViewManagerTest.java
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── github/
│       │               └── florent37/
│       │                   └── androidunittest/
│       │                       └── ApplicationTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── github/
│       │   │           └── florent37/
│       │   │               └── testsample/
│       │   │                   ├── MainActivity.java
│       │   │                   ├── MainFragment.java
│       │   │                   ├── MainView.java
│       │   │                   ├── MyApplication.java
│       │   │                   └── model/
│       │   │                       └── User.java
│       │   └── res/
│       │       ├── layout/
│       │       │   ├── activity_main.xml
│       │       │   └── fragment_main.xml
│       │       ├── values/
│       │       │   ├── colors.xml
│       │       │   ├── dimens.xml
│       │       │   ├── strings.xml
│       │       │   └── styles.xml
│       │       └── values-w820dp/
│       │           └── dimens.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── github/
│                       └── florent37/
│                           └── testsample/
│                               ├── BasicActivityTest.java
│                               ├── CustomTestRunner.java
│                               ├── MainActivityTest.java
│                               ├── MainFragmentTest.java
│                               ├── MainFragmentWithActivityTest.java
│                               ├── MainViewTest.java
│                               ├── StateActivityTest.java
│                               └── TestMyApplication.java
├── build.gradle
├── gradle/
│   ├── bintray-android-v1.gradle
│   ├── bintray-java-v1.gradle
│   ├── install-v1.gradle
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Built application files
*.apk
*.ap_

# Files for the Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
captures/

.gradle
.idea
*.iml
**/build/*

================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright {yyyy} {name of copyright owner}

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
# Android Unit Test

Save time & clear your unit tests on Android ! 

Use annotations to inject Context, Activities, Fragments and Views into your tests


<a href="https://goo.gl/WXW8Dc">
  <img alt="Android app on Google Play" src="https://developer.android.com/images/brand/en_app_rgb_wo_45.png" />
</a>


# Usage

```java
@RunWith(CustomTestRunner.class)
public class MainActivityTest {
    @Rule public AndroidUnitTest androidUnitTest = AndroidUnitTest.rule();

    @RContect Context context; //inject the app context
    @RActivity MainActivity activity; //generates the tested activity
    @Mock User user; //mock an user

    @Test
    public void testDisplayUser() throws Exception {
        // Given
        given(user.getName()).willReturn("florent");
        
        // When
        activity.display(user);
        
        // Then
        assertThat(activity.textView.getText()).isEqualTo("florent");
    }
}
```

## TestRunner

Simplify Robolectric Integration

```java
public class CustomTestRunner extends AndroidUnitTestRunner {
    public CustomTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass, BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE, BuildConfig.APPLICATION_ID, TestMyApplication.class);
    }
}
```

## Activity

Set initial activity state (by default activity is created())

```java
@RunWith(CustomTestRunner.class)
public class MyTest {
    @Rule public AndroidUnitTest androidUnitTest = AndroidUnitTest.rule();

    @RActivity(state = CREATED / STARTED / RESUMED / PAUSED / STOPPED / DESTROYED)
    MainActivity activity;
    
    @Test
    public void testMyFunction(){
         androidUnitTest.activity().resume();
    }

}
```

Note that the injected activity is a spy !

```java
verify(activity, times(2)).someMethod(anyInt());
```

## Context

Retrieve Context easily

```java
@RunWith(CustomTestRunner.class)
public class MyTest {
    @Rule public AndroidUnitTest androidUnitTest = AndroidUnitTest.rule();

    @RContext Context context;
}
```

Note that the injected context is a spy !

```java
verify(context, times(2)).someMethod(anyInt());
```

## View

```java
@RunWith(CustomTestRunner.class)
public class MyTest {
    @Rule public AndroidUnitTest androidUnitTest = AndroidUnitTest.rule();

    @RView CustomView customView;
    
    @Test
    public void testDisplayUser() throws Exception {
        // Given
        given(user.getName()).willReturn("florent");
        
        // When
        mainView.display(user);
        
        // Then
        verify(customView).displayText("florent");
    }
}
```

Note that the injected view is a spy !

## Fragment

```java
@RunWith(CustomTestRunner.class)
public class MyTest {
    @Rule public AndroidUnitTest androidUnitTest = AndroidUnitTest.rule();

    @RFragment MyFragment myFragment;
    @Mock User user;
    
    @Test
    public void testDisplayUser() throws Exception {
        // Given
        given(user.getName()).willReturn("florent");
        
        // When
        myFragment.display(user);
        
        // Then
        verify(myFragment).displayText("florent");
    }
}
```

```java
@RunWith(CustomTestRunner.class)
public class MyTest {
    @Rule public AndroidUnitTest androidUnitTest = AndroidUnitTest.rule();

    @RFragment(
        attached = true / false,
        tag = "fragmentTag"
    )
    MyFragment myFragment;
        
    @Test
    public void testMyFunction() throws Exception {
        androidUnitTest.fragment().addToActivity(myFragment)
    }
}
```

Note that the injected fragment is a spy !

# Download

<a href='https://ko-fi.com/A160LCC' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi1.png?v=0' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>

 [ ![Download](https://api.bintray.com/packages/florent37/maven/AndroidUnitTest/images/download.svg) ](https://bintray.com/florent37/maven/AndroidUnitTest/_latestVersion)

```java
testCompile 'com.github.florent37:androidunittest:(last version)'

testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
testCompile 'org.robolectric:robolectric:3.0'
```

# Credits

Author: Florent Champigny 


<a href="https://goo.gl/WXW8Dc">
  <img alt="Android app on Google Play" src="https://developer.android.com/images/brand/en_app_rgb_wo_45.png" />
</a>

<a href="https://plus.google.com/+florentchampigny">
  <img alt="Follow me on Google+"
       src="https://raw.githubusercontent.com/florent37/DaVinci/master/mobile/src/main/res/drawable-hdpi/gplus.png" />
</a>
<a href="https://twitter.com/florent_champ">
  <img alt="Follow me on Twitter"
       src="https://raw.githubusercontent.com/florent37/DaVinci/master/mobile/src/main/res/drawable-hdpi/twitter.png" />
</a>
<a href="https://fr.linkedin.com/in/florentchampigny">
  <img alt="Follow me on LinkedIn"
       src="https://raw.githubusercontent.com/florent37/DaVinci/master/mobile/src/main/res/drawable-hdpi/linkedin.png" />
</a>

License
--------

    Copyright 2016 florent37, Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.


================================================
FILE: androidunittest/.gitignore
================================================
/build


================================================
FILE: androidunittest/build.gradle
================================================
apply plugin: 'com.android.library'

android {
    compileSdkVersion project.sdk
    buildToolsVersion project.buildTools

    defaultConfig {
        minSdkVersion project.minSdk
        targetSdkVersion project.sdk
        versionCode 1
        versionName "1.0"
    }
}

dependencies {
    compile(
            'junit:junit:4.12',
            'org.mockito:mockito-core:1.10.19',
            'org.robolectric:robolectric:3.0',
            'com.android.support:support-annotations:'+project.supportVersion,
            'com.android.support:appcompat-v7:'+project.supportVersion
    )
    testCompile 'com.google.truth:truth:0.28'
}


ext {
    bintrayRepo = 'maven'
    bintrayName = 'AndroidUnitTest'
    orgName = 'florent37'

    publishedGroupId = 'com.github.florent37'
    libraryName = 'AndroidUnitTest'
    artifact = 'androidunittest'

    libraryDescription = 'AndroidUnitTest'

    siteUrl = 'https://github.com/florent37/AndroidUnitTest'
    gitUrl = 'https://github.com/florent37/AndroidUnitTest.git'

    libraryVersion = rootProject.ext.libraryVersion

    developerId = 'florent37'
    developerName = 'Florent Champigny'
    developerEmail = 'champigny.florent@gmail.com'

    licenseName = 'The Apache Software License, Version 2.0'
    licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
    allLicenses = ["Apache-2.0"]
}

if (project.rootProject.file('local.properties').exists()) {
    apply from: rootProject.file('gradle/install-v1.gradle')
    apply from: rootProject.file('gradle/bintray-android-v1.gradle')
}

================================================
FILE: androidunittest/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/florentchampigny/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: androidunittest/src/androidTest/java/com/github/florent37/androidunittest/ApplicationTest.java
================================================
package com.github.florent37.androidunittest;

import android.app.Application;
import android.test.ApplicationTestCase;

/**
 * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 */
public class ApplicationTest extends ApplicationTestCase<Application> {
    public ApplicationTest() {
        super(Application.class);
    }
}

================================================
FILE: androidunittest/src/main/AndroidManifest.xml
================================================
<manifest package="com.github.florent37.androidunittest"
          xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:supportsRtl="true"
        >

    </application>

</manifest>


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/AndroidUnitTest.java
================================================
package com.github.florent37.androidunittest;

import android.support.annotation.Nullable;

import com.github.florent37.androidunittest.controllers.ControllerActivity;
import com.github.florent37.androidunittest.controllers.ControllerFragment;

import org.junit.rules.MethodRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.robolectric.util.ActivityController;

/**
 * Created by florentchampigny on 07/05/2016.
 */
public class AndroidUnitTest implements MethodRule {

    ControllerActivity controllerActivity;
    ControllerFragment controllerFragment;
    @Nullable ActivityController activityController;
    private AndroidUnitTestAnnotations androidUnitTestAnnotations;

    protected AndroidUnitTest() {
        androidUnitTestAnnotations = new AndroidUnitTestAnnotations(AndroidUnitTest.this);
        controllerActivity = new ControllerActivity(this);
        controllerFragment = new ControllerFragment(this);
    }

    public static AndroidUnitTest rule() {
        return new AndroidUnitTest();
    }

    @Override
    public Statement apply(final Statement base, FrameworkMethod method, final Object target) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                MockitoAnnotations.initMocks(target);
                androidUnitTestAnnotations.init(target);
                base.evaluate();
                Mockito.validateMockitoUsage();
            }
        };
    }

    @Nullable
    public ActivityController getActivityController() {
        return activityController;
    }

    public void setActivityController(@Nullable ActivityController activityController) {
        this.activityController = activityController;
    }

    public AndroidUnitTestAnnotations getAndroidUnitTestAnnotations() {
        return androidUnitTestAnnotations;
    }

    public ControllerActivity activity() {
        return controllerActivity;
    }

    public ControllerFragment fragment() {
        return controllerFragment;
    }

}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/AndroidUnitTestAnnotations.java
================================================
package com.github.florent37.androidunittest;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;

import com.github.florent37.androidunittest.managers.AbstractAnnotationManager;
import com.github.florent37.androidunittest.managers.AnnotationActivityManager;
import com.github.florent37.androidunittest.managers.AnnotationContextManager;
import com.github.florent37.androidunittest.managers.AnnotationFragmentManager;
import com.github.florent37.androidunittest.managers.AnnotationViewManager;

import org.robolectric.RuntimeEnvironment;

import java.lang.reflect.Field;

/**
 * Created by florentchampigny on 07/05/2016.
 */
public class AndroidUnitTestAnnotations {
    final Context context;

    AndroidUnitTest androidUnitTest;
    Object target;

    AbstractAnnotationManager managers[];
    AnnotationActivityManager activityManager;
    AnnotationFragmentManager fragmentManager;


    private AndroidUnitTestAnnotations() {
        context = RuntimeEnvironment.application;
    }

    public AndroidUnitTestAnnotations(AndroidUnitTest androidUnitTest) {
        this();

        this.androidUnitTest = androidUnitTest;
    }


    public AndroidUnitTestAnnotations init(Object target) {
        //find @Activity
        //find @Fragment
        //find @RContext -> RuntimeEnvironment.application;
        this.target = target;

        instantiate();
        scan();
        execute();
        return this;
    }


    public void updateActivity() {
        activityManager.updateActivity(target);
    }

    public void addToActivity(@NonNull Fragment fragment) {
        fragmentManager.addToActivity(target, fragment);
    }

    public void removeFromActivity(@NonNull Fragment fragment) {
        fragmentManager.removeFromActivity(fragment);
    }


    /**
     * Instantiate the list of abstract annotation managers
     */
    private void instantiate() {
        managers = new AbstractAnnotationManager[]{
                new AnnotationContextManager(androidUnitTest),
                new AnnotationActivityManager(androidUnitTest),
                new AnnotationFragmentManager(androidUnitTest),
                new AnnotationViewManager(androidUnitTest)
        };

        activityManager = (AnnotationActivityManager) managers[1];
        fragmentManager = (AnnotationFragmentManager) managers[2];
    }

    /**
     * Scan the target to populate the managers
     */
    private void scan() {
        for (Field field : target.getClass().getDeclaredFields()) {
            for (AbstractAnnotationManager manager : managers)
                if (manager.canManage(field))
                    manager.scanned(field);
        }
    }

    /**
     * Execute the different managers
     *
     * given their positions, it represents their dependencies
     */
    private void execute() {
        for (AbstractAnnotationManager manager : managers)
            manager.execute(target, context);
    }
}

================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/AndroidUnitTestRunner.java
================================================
package com.github.florent37.androidunittest;

import android.app.Application;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import org.junit.runners.model.InitializationError;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.internal.bytecode.InstrumentationConfiguration;
import org.robolectric.internal.bytecode.ShadowMap;
import org.robolectric.manifest.AndroidManifest;

import java.io.File;
import java.util.Properties;

public class AndroidUnitTestRunner extends RobolectricTestRunner {

    public static final String PATH_ASSET = "../../../assets/";
    public static final String PATH_RESOURCE = "../../../res/merged/";
    public static final String PATH_MANIFEST = "build/intermediates/manifests/full/%s/AndroidManifest.xml";

    public static final String CONFIG_APPLICATION = "application";
    public static final String CONFIG_MANIFEST = "manifest";
    public static final String CONFIG_ASSET_DIR = "assetDir";
    public static final String CONFIG_RESOURCE_DIR = "resourceDir";
    public static final String CONFIG_PACKAGE_NAME = "packageName";
    public static final String CONFIG_SDK = "sdk";

    public static final String PATH_PREFIX = "app/";
    final String packageName;
    final String flavor;
    final String buildType;
    final Class<? extends Application> applicationClass;

    public AndroidUnitTestRunner(Class<?> testClass, @NonNull String flavor, @NonNull String buildType, String packageName, @Nullable Class<? extends Application> applicationClass) throws InitializationError {
        super(testClass);
        this.packageName = packageName;
        this.applicationClass = applicationClass;
        this.flavor = flavor;
        this.buildType = buildType;
    }

    public String getPathManifest() {
        String path = buildType;
        if (flavor != null && !flavor.isEmpty()) {
            path = String.format("%s/%s", flavor, path);
        }
        return String.format(PATH_MANIFEST, path);
    }

    public String getPathAssets() {
        String prePath = "";
        String postPath = buildType;
        if (flavor != null && !flavor.isEmpty()) {
            prePath = "../";
            postPath = String.format("%s/%s", flavor, postPath);
        }
        return prePath + PATH_ASSET + postPath;
    }

    public String getPathResources() {
        String prePath = "";
        String postPath = buildType;
        if (flavor != null && !flavor.isEmpty()) {
            prePath = "../";
            postPath = String.format("%s/%s", flavor, postPath);
        }
        return prePath + PATH_RESOURCE + postPath;
    }

    @Override
    public InstrumentationConfiguration createClassLoaderConfig() {
        InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder();
        return builder.build();
    }

    @Override
    protected AndroidManifest getAppManifest(Config config) {
        String path = getPathManifest();

        // android studio has a different execution root for tests than pure gradle
        // so we avoid here manual effort to get them running inside android studio
        if (!new File(path).exists()) {
            path = PATH_PREFIX + path;
        }

        config = overwriteConfig(config, CONFIG_MANIFEST, path);
        config = overwriteConfig(config, CONFIG_ASSET_DIR, getPathAssets());
        config = overwriteConfig(config, CONFIG_RESOURCE_DIR, getPathResources());
        if (packageName != null) {
            config = overwriteConfig(config, CONFIG_PACKAGE_NAME, packageName);
        }
        if (applicationClass != null) {
            config = overwriteConfig(config, CONFIG_APPLICATION, applicationClass.getCanonicalName());
        }
        return super.getAppManifest(config);
    }

    @Override
    protected int pickSdkVersion(Config config, AndroidManifest manifest) {
        config = overwriteConfig(config, CONFIG_SDK, String.valueOf(Build.VERSION_CODES.JELLY_BEAN));
        return super.pickSdkVersion(config, manifest);
    }

    @Override
    protected ShadowMap createShadowMap() {
        return super.createShadowMap()
            .newBuilder()
            .build();
    }

    protected Config.Implementation overwriteConfig(Config config, String key, String value) {
        Properties properties = new Properties();
        properties.setProperty(key, value);
        return new Config.Implementation(config, Config.Implementation.fromProperties(properties));
    }
}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/annotations/RActivity.java
================================================
package com.github.florent37.androidunittest.annotations;

import com.github.florent37.androidunittest.states.ActivityState;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Created by florentchampigny on 07/05/2016.
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface RActivity {
    ActivityState state() default ActivityState.CREATED;
}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/annotations/RContext.java
================================================
package com.github.florent37.androidunittest.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Created by florentchampigny on 07/05/2016.
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface RContext {
}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/annotations/RFragment.java
================================================
package com.github.florent37.androidunittest.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Created by florentchampigny on 07/05/2016.
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface RFragment {
    boolean attached() default true;
    String tag() default "";
}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/annotations/RView.java
================================================
package com.github.florent37.androidunittest.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Created by florentchampigny on 07/05/2016.
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface RView {
    boolean attached() default true;
}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/controllers/ControllerActivity.java
================================================
package com.github.florent37.androidunittest.controllers;

import android.app.Activity;
import android.support.annotation.Nullable;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RActivity;
import com.github.florent37.androidunittest.states.ActivityState;

import org.mockito.Mockito;
import org.robolectric.Robolectric;
import org.robolectric.util.ActivityController;

/**
 * Created by florentchampigny on 08/05/2016.
 */
public class ControllerActivity {

    private AndroidUnitTest androidUnitTest;

    public ControllerActivity(AndroidUnitTest androidUnitTest) {
        this.androidUnitTest = androidUnitTest;
    }

    @Nullable
    public Activity get() {
        if (androidUnitTest.getActivityController() != null) {
            return (Activity) androidUnitTest.getActivityController().get();
        }
        return null;
    }

    @Nullable
    public ActivityController getActivityController() {
        if (androidUnitTest.getActivityController() != null) {
            return androidUnitTest.getActivityController();
        }
        return null;
    }

    public Activity createAndInitActivity(Class activityClass, @Nullable RActivity activityAnnotation) {
        ActivityController activityController = ActivityController.of(Robolectric.getShadowsAdapter(), activityClass);
        androidUnitTest.setActivityController(activityController);
        if (activityAnnotation != null) {
            ActivityState activityState = activityAnnotation.state();
            setActivityState(activityController, activityState);
        }
        Activity activity = (Activity) activityController.get();
        return Mockito.spy(activity);
    }

    public ControllerActivity resume() {
        if (androidUnitTest.getActivityController() != null) {
            androidUnitTest.getActivityController().resume();
            androidUnitTest.getAndroidUnitTestAnnotations().updateActivity();
        }
        return this;
    }

    public ControllerActivity create() {
        if (androidUnitTest.getActivityController() != null) {
            androidUnitTest.getActivityController().create();
            androidUnitTest.getAndroidUnitTestAnnotations().updateActivity();
        }
        return this;
    }

    public ControllerActivity start() {
        if (androidUnitTest.getActivityController() != null) {
            androidUnitTest.getActivityController().start();
            androidUnitTest.getAndroidUnitTestAnnotations().updateActivity();
        }
        return this;
    }

    public ControllerActivity pause() {
        if (androidUnitTest.getActivityController() != null) {
            androidUnitTest.getActivityController().pause();
            androidUnitTest.getAndroidUnitTestAnnotations().updateActivity();
        }
        return this;
    }

    public ControllerActivity stop() {
        if (androidUnitTest.getActivityController() != null) {
            androidUnitTest.getActivityController().stop();
            androidUnitTest.getAndroidUnitTestAnnotations().updateActivity();
        }
        return this;
    }

    public ControllerActivity destroy() {
        if (androidUnitTest.getActivityController() != null) {
            androidUnitTest.getActivityController().destroy();
            androidUnitTest.getAndroidUnitTestAnnotations().updateActivity();
        }
        return this;
    }

    public ControllerActivity setActivityState(ActivityState activityState) {
        if (androidUnitTest.getActivityController() != null) {
            setActivityState(getActivityController(), activityState);
        }
        return this;
    }

    public ControllerActivity setActivityState(ActivityController activityController, ActivityState activityState) {
        ActivityState init = ActivityState.CREATED;

        while (init != null && init.isLowerOrEquals(activityState)) {
            System.out.println(init);
            applyState(init, activityController);
            init = init.next();
        }

        return this;
    }

    private void applyState(ActivityState state,
                            ActivityController controller) {
        switch (state) {
            case STARTED:
                controller.start();
                break;
            case RESUMED:
                controller.resume();
                break;
            case PAUSED:
                controller.pause();
                break;
            case STOPPED:
                controller.stop();
                break;
            case DESTROYED:
                controller.destroy();
                break;
            case CREATED:
            default:
                controller.create();
                break;
        }
    }

}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/controllers/ControllerFragment.java
================================================
package com.github.florent37.androidunittest.controllers;

import android.support.v4.app.Fragment;

import com.github.florent37.androidunittest.AndroidUnitTest;

/**
 * Created by florentchampigny on 08/05/2016.
 */
public class ControllerFragment {
    private AndroidUnitTest androidUnitTest;
    public ControllerFragment(AndroidUnitTest androidUnitTest) {
        this.androidUnitTest = androidUnitTest;
    }

    public ControllerFragment attachToActivity(Fragment fragment){
        if (androidUnitTest.activity().get() == null) {

        }
        androidUnitTest.getAndroidUnitTestAnnotations().addToActivity(fragment);
        return this;
    }

    public ControllerFragment removeFromActivity(Fragment fragment){
        androidUnitTest.getAndroidUnitTestAnnotations().removeFromActivity(fragment);
        return this;
    }
}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AbstractAnnotationManager.java
================================================
package com.github.florent37.androidunittest.managers;

import android.content.Context;
import android.support.annotation.NonNull;

import com.github.florent37.androidunittest.AndroidUnitTest;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

/**
 * Created by kevinleperf on 18/05/16.
 */
public abstract class AbstractAnnotationManager {
    private AndroidUnitTest mAndroidUnitTest;

    private AbstractAnnotationManager() {

    }

    public AbstractAnnotationManager(AndroidUnitTest parent) {
        this();

        mAndroidUnitTest = parent;
    }

    public final boolean canManage(@NonNull Field field) {
        return field.isAnnotationPresent(canManagerInternal());
    }

    @NonNull
    protected abstract Class<? extends Annotation> canManagerInternal();

    /**
     * Method called by the AndroidUnitTestAnnotations class
     * during the scan() method
     *
     * @param field the scanned field to manage internally
     */
    public abstract void scanned(@NonNull Field field);

    /**
     * Method called by the AndroidUnitTestAnnotations class
     * during the execute() method
     *
     * @param object  the object to be applied
     * @param context the current app context
     */
    public abstract void execute(@NonNull Object object,
                                 @NonNull Context context);

    @NonNull
    protected AndroidUnitTest getAndroidUnitTest() {
        return mAndroidUnitTest;
    }

}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AnnotationActivityManager.java
================================================
package com.github.florent37.androidunittest.managers;

import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RActivity;

import org.mockito.internal.util.reflection.FieldSetter;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

/**
 * Created by kevinleperf on 18/05/16.
 */
public class AnnotationActivityManager extends AbstractAnnotationManager {

    @VisibleForTesting Field activityField;

    public AnnotationActivityManager(AndroidUnitTest parent) {
        super(parent);

        //createAndInitActivity(null, FragmentActivity.class, null);
        //parent.activity().setActivityState(ActivityState.CREATED);
        //useless create() here since in createAndInitActivity
        //parent.getActivityController().create();
    }

    @Override
    public void scanned(@NonNull Field field) {
        activityField = field;
    }

    @Override
    public void execute(@NonNull Object object, @NonNull Context context) {
        if (activityField != null) {
            createAndInitActivity(object,
                    activityField.getType(),
                    activityField.getAnnotation(RActivity.class));
        }//activityField is null, using standard FragmentActivity from constructor
    }

    public Field getScanned() {
        return activityField;
    }

    public void createAndInitActivity(@Nullable Object target, Class activityClass, @Nullable RActivity activityAnnotation) {
        Activity activity = getAndroidUnitTest().activity().createAndInitActivity(activityClass, activityAnnotation);
        if (this.activityField != null && target != null) {
            new FieldSetter(target, this.activityField).set(activity);
        }
    }

    public void updateActivity(Object target) {
        new FieldSetter(target, this.activityField)
                .set(getAndroidUnitTest().getActivityController().get());
    }

    @NonNull
    @Override
    protected Class<? extends Annotation> canManagerInternal() {
        return RActivity.class;
    }
}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AnnotationContextManager.java
================================================
package com.github.florent37.androidunittest.managers;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RContext;

import org.mockito.Mockito;
import org.mockito.internal.util.reflection.FieldSetter;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

/**
 * Created by kevinleperf on 18/05/16.
 */
public class AnnotationContextManager extends AbstractAnnotationManager {

    @VisibleForTesting Field contextField;

    public AnnotationContextManager(AndroidUnitTest parent) {
        super(parent);
    }

    @Override
    public void scanned(@NonNull Field field) {
        contextField = field;
    }

    @Override
    public void execute(@NonNull Object target, @NonNull Context context) {
        if (contextField != null) {
            Context appContext = context;
            appContext = Mockito.spy(appContext);
            new FieldSetter(target, this.contextField).set(appContext);
        }
    }

    @NonNull
    @Override
    protected Class<? extends Annotation> canManagerInternal() {
        return RContext.class;
    }
}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AnnotationFragmentManager.java
================================================
package com.github.florent37.androidunittest.managers;

import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RFragment;
import com.github.florent37.androidunittest.controllers.ControllerActivity;
import com.github.florent37.androidunittest.states.ActivityState;

import org.mockito.Mockito;
import org.mockito.internal.util.reflection.FieldReader;
import org.mockito.internal.util.reflection.FieldSetter;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashSet;

/**
 * Created by kevinleperf on 18/05/16.
 */
public class AnnotationFragmentManager extends AbstractAnnotationManager {
    @VisibleForTesting final HashSet<Field> fragmentFields;

    public AnnotationFragmentManager(AndroidUnitTest parent) {
        super(parent);

        fragmentFields = new HashSet<>();
    }

    public static void addToActivity(Activity activity, Fragment fragment, String tag) {
        if (activity instanceof FragmentActivity) {
            FragmentActivity fragmentActivity = (FragmentActivity) activity;
            fragmentActivity.getSupportFragmentManager().beginTransaction()
                .add(fragment, tag)
                .commit();
        }
    }

    public static void removeFromActivity(Activity activity, Fragment fragment) {
        if (activity instanceof FragmentActivity) {
            FragmentActivity fragmentActivity = (FragmentActivity) activity;
            fragmentActivity.getSupportFragmentManager().beginTransaction()
                .remove(fragment)
                .commit();
        }
    }

    @Override
    public void scanned(@NonNull Field field) {
        fragmentFields.add(field);
    }

    @Override
    public void execute(@NonNull Object object, @NonNull Context context) {
        for (Field fragment : fragmentFields) {
            initFragment(object, fragment);
        }
    }

    public void initFragment(@NonNull Object target, @NonNull Field fragmentField) {
        RFragment fragmentAnnotation = fragmentField.getAnnotation(RFragment.class);

        Class fragmentClass = fragmentField.getType();
        Fragment fragment = null;
        try {
            fragment = (Fragment) fragmentClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalStateException("Impossible to instantiate a fragment using the default constructor");
        }

        fragment = Mockito.spy(fragment);
        new FieldSetter(target, fragmentField).set(fragment);

        //if no activity is create, the default activity manager behaviour is to create one
        /*if (this.activityField == null) {
            createActivity(FragmentActivity.class, null);
            androidUnitTest.activity().setActivityState(ActivityState.CREATED);
        }*/

        if (fragmentAnnotation.attached()) {
            String tag = fragmentAnnotation.tag();
            if (tag == null || tag.isEmpty()) {
                tag = fragment.getClass().toString();
            }
            addToActivity(getActivity(), fragment, tag);
        }
    }

    public void addToActivity(@NonNull Object target, Fragment fragment) {
        String tag = null;
        for (Field fragmentField : fragmentFields) {
            Fragment fragmentOfField = (Fragment) new FieldReader(target, fragmentField).read();
            if (fragment == fragmentOfField) {
                RFragment fragmentAnnotation = fragmentField.getAnnotation(RFragment.class);
                tag = fragmentAnnotation.tag();
            }
        }
        if (tag == null || tag.isEmpty()) {
            tag = fragment.getClass().toString();
        }

        ControllerActivity controllerActivity = getAndroidUnitTest().activity();
        //if no activity is create, the default activity manager behaviour is to create one
        if (controllerActivity.get() == null) {
            controllerActivity.createAndInitActivity(FragmentActivity.class, null);
            controllerActivity.setActivityState(ActivityState.CREATED);
        }

        AnnotationFragmentManager.addToActivity(getActivity(), fragment, tag);
    }

    public void removeFromActivity(Fragment fragment) {
        AnnotationFragmentManager.removeFromActivity(getActivity(), fragment);
    }

    @NonNull
    @Override
    protected Class<? extends Annotation> canManagerInternal() {
        return RFragment.class;
    }

    private Activity getActivity() {
        return getAndroidUnitTest().activity().get();
    }
}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AnnotationViewManager.java
================================================
package com.github.florent37.androidunittest.managers;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.view.View;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RView;

import org.mockito.Mockito;
import org.mockito.internal.util.reflection.FieldSetter;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;

/**
 * Created by kevinleperf on 18/05/16.
 */
public class AnnotationViewManager extends AbstractAnnotationManager {

    @VisibleForTesting Set<Field> fields;

    public AnnotationViewManager(AndroidUnitTest androidUnitTest) {
        super(androidUnitTest);

        fields = new HashSet<>();
    }

    @Override
    public void scanned(@NonNull Field field) {
        fields.add(field);
    }

    @Override
    public void execute(@NonNull Object object, @NonNull Context context) {
        for (Field view : fields) {
            initView(object, context, view);
        }
    }

    @NonNull
    @Override
    protected Class<? extends Annotation> canManagerInternal() {
        return RView.class;
    }

    private void initView(@NonNull Object target, @NonNull Context context, @NonNull Field viewField) {
        Class viewClass = viewField.getType();
        View view = null;
        try {
            view = (View) viewClass.getDeclaredConstructor(Context.class).newInstance(context);
        } catch (Exception e) {
            e.printStackTrace();
        }
        view = Mockito.spy(view);
        new FieldSetter(target, viewField).set(view);
    }

}


================================================
FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/states/ActivityState.java
================================================
package com.github.florent37.androidunittest.states;

import android.support.annotation.NonNull;

/**
 * Created by kevinleperf on 14/05/16.
 * <p/>
 * A ActivityState describe the initial state of an activity at binding
 */
public enum ActivityState {
    //reverse ordered to prevent illegal forward reference
    DESTROYED(null),
    STOPPED(ActivityState.DESTROYED),
    PAUSED(ActivityState.STOPPED),
    RESUMED(ActivityState.PAUSED),
    STARTED(ActivityState.RESUMED),
    CREATED(ActivityState.STARTED);


    private ActivityState mNext;

    ActivityState(ActivityState next) {
        mNext = next;
    }

    public ActivityState next() {
        return mNext;
    }

    /**
     * Check wether the given ActivityState is before or at least the same element as this instance
     *
     * commonly used to check if the previous state can be call
     * for instance, checking if Resume can be used before Paused, it will returns true
     * whereas, testing destroy against resume will return false
     * @param state
     * @return
     */
    public boolean isLowerOrEquals(@NonNull ActivityState state) {
        return ordinal() >= state.ordinal(); //since we are in the reverse order
        //it is not <= but =>
    }
}


================================================
FILE: androidunittest/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">AndroidUnitTest</string>
</resources>


================================================
FILE: androidunittest/src/test/java/com/github/florent37/androidunittest/managers/AnnotationActivityManagerTest.java
================================================
package com.github.florent37.androidunittest.managers;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RActivity;
import com.github.florent37.androidunittest.controllers.ControllerActivity;
import com.github.florent37.androidunittest.states.ActivityState;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.util.ActivityController;

import java.lang.reflect.Field;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.verify;

/**
 * Created by florentchampigny on 19/05/2016.
 */
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class AnnotationActivityManagerTest {

    @Rule public MockitoRule rule = MockitoJUnit.rule();

    @Mock AndroidUnitTest androidUnitTest;
    ControllerActivity controllerActivity;
    @Mock Activity activity;
    @InjectMocks AnnotationActivityManager manager;

    @Before
    public void setUp() throws Exception {
        controllerActivity = new ControllerActivity(androidUnitTest);
        given(androidUnitTest.activity()).willReturn(controllerActivity);
    }

    @Test
    public void testCanManagerInternal() throws Exception {
        // Given
        // When
        Object canManage = manager.canManagerInternal();
        // Then
        assertThat(canManage).isNotNull();
        assertThat(canManage).isEqualTo(RActivity.class);
    }

    @Test
    public void testScanned() throws Exception {
        // Given
        TestObject testObject = new TestObject();
        Field field = testObject.getClass().getDeclaredField("activity");
        // When
        manager.scanned(field);
        // Then
        assertThat(manager.activityField).isEqualTo(field);
    }

    @Test
    public void testExecute() throws Exception {
        // Given
        TestObject testObject = new TestObject();
        Context context = new Application();
        manager.activityField = testObject.getClass().getDeclaredField("activity");
        // When
        manager.execute(testObject, context);
        //Then
        assertThat(testObject.activity).isNotNull();
        assertThat(testObject.activity.created).isTrue();
        verify(androidUnitTest).setActivityController(any(ActivityController.class));
    }

    @Test
    public void testExecuteState() throws Exception {
        // Given
        TestObjectState testObject = new TestObjectState();
        Context context = new Application();
        manager.activityField = testObject.getClass().getDeclaredField("activity");
        // When
        manager.execute(testObject, context);
        //Then
        assertThat(testObject.activity).isNotNull();
        assertThat(testObject.activity.created).isTrue();
        assertThat(testObject.activity.started).isTrue();
        assertThat(testObject.activity.resumed).isTrue();
        verify(androidUnitTest).setActivityController(any(ActivityController.class));
    }

    static class TestObject {
        @RActivity TestActivity activity;
    }

    static class TestObjectState {
        @RActivity(state = ActivityState.RESUMED) TestActivity activity;
    }

    static class TestActivity extends Activity {
        boolean created = false;
        boolean resumed = false;
        boolean started = false;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            created = true;
        }

        @Override
        protected void onStart() {
            super.onStart();
            started = true;
        }

        @Override
        protected void onResume() {
            super.onResume();
            resumed = true;
        }
    }
}

================================================
FILE: androidunittest/src/test/java/com/github/florent37/androidunittest/managers/AnnotationContextManagerTest.java
================================================
package com.github.florent37.androidunittest.managers;

import android.app.Application;
import android.content.Context;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RContext;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.lang.reflect.Field;

import static com.google.common.truth.Truth.assertThat;

/**
 * Created by florentchampigny on 19/05/2016.
 */
@RunWith(MockitoJUnitRunner.class)
public class AnnotationContextManagerTest {

    @Mock AndroidUnitTest androidUnitTest;
    @InjectMocks AnnotationContextManager manager;

    @Test
    public void testCanManagerInternal() throws Exception {
        // Given
        // When
        Object canManage = manager.canManagerInternal();
        // Then
        assertThat(canManage).isNotNull();
        assertThat(canManage).isEqualTo(RContext.class);
    }

    @Test
    public void testScanned() throws Exception {
        // Given
        TestObject testObject = new TestObject();
        Field field = testObject.getClass().getDeclaredField("context");
        // When
        manager.scanned(field);
        // Then
        assertThat(manager.contextField).isEqualTo(field);
    }

    @Test
    public void testExecute() throws Exception {
        // Given
        TestObject testObject = new TestObject();
        Context context = new Application();
        manager.contextField = testObject.getClass().getDeclaredField("context");
        // When
        manager.execute(testObject, context);
        //Then
        assertThat(testObject.context).isNotNull();
    }

    static class TestObject {
        @RContext Context context;
    }
}

================================================
FILE: androidunittest/src/test/java/com/github/florent37/androidunittest/managers/AnnotationFragmentManagerTest.java
================================================
package com.github.florent37.androidunittest.managers;

import android.app.Application;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RFragment;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import java.lang.reflect.Field;

import static com.google.common.truth.Truth.assertThat;

/**
 * Created by florentchampigny on 19/05/2016.
 */
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class AnnotationFragmentManagerTest {

    @Rule public MockitoRule rule = MockitoJUnit.rule();

    AndroidUnitTest androidUnitTest;
    AnnotationFragmentManager manager;

    @Before
    public void setUp() throws Exception {
        androidUnitTest = AndroidUnitTest.rule();
        manager = new AnnotationFragmentManager(androidUnitTest);
    }

    @Test
    public void testCanManagerInternal() throws Exception {
        // Given
        // When
        Object canManage = manager.canManagerInternal();
        // Then
        assertThat(canManage).isNotNull();
        assertThat(canManage).isEqualTo(RFragment.class);
    }

    @Test
    public void testScanned() throws Exception {
        // Given
        TestObject testObject = new TestObject();
        Field field = testObject.getClass().getDeclaredField("fragment1");
        // When
        manager.scanned(field);
        // Then
        assertThat(manager.fragmentFields).contains(field);
    }

    @Test
    public void testExecute() throws Exception {
        // Given
        TestObject testObject = new TestObject();
        Context context = new Application();
        manager.fragmentFields.add(testObject.getClass().getDeclaredField("fragment1"));
        manager.fragmentFields.add(testObject.getClass().getDeclaredField("fragment2"));
        // When
        manager.execute(testObject, context);
        //Then
        assertThat(testObject.fragment1).isNotNull();
        assertThat(testObject.fragment2).isNotNull();
    }

    @Test
    public void testAddToActivity() throws Exception {
        // Given
        TestObject target = new TestObject();
        target.fragment1 = new Fragment();
        // When
        manager.addToActivity(target, target.fragment1);
        // Then
        assertThat(target.fragment1.getActivity()).isNotNull();
    }

    @Test
    public void testRemoveFromActivity() throws Exception {
        // Given
        TestObject target = new TestObject();
        target.fragment1 = new Fragment();
        manager.addToActivity(target, target.fragment1);
        // When
        manager.removeFromActivity(target.fragment1);
        // Then
        assertThat(target.fragment1.getActivity()).isNull();
    }

    @Test
    public void testAddToActivityWithTag() throws Exception {
        // Given
        TestObject target = new TestObject();
        FragmentActivity activity = Robolectric.buildActivity(FragmentActivity.class).create().get();
        target.fragment1 = new Fragment();
        String tag = "TAG";
        // When
        AnnotationFragmentManager.addToActivity(activity, target.fragment1, tag);
        // Then
        assertThat(target.fragment1.getActivity()).isNotNull();
    }

    static class TestObject {
        @RFragment Fragment fragment1;
        @RFragment Fragment fragment2;
    }

}

================================================
FILE: androidunittest/src/test/java/com/github/florent37/androidunittest/managers/AnnotationViewManagerTest.java
================================================
package com.github.florent37.androidunittest.managers;

import android.app.Application;
import android.content.Context;
import android.view.View;
import android.widget.TextView;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RView;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.lang.reflect.Field;

import static com.google.common.truth.Truth.assertThat;

/**
 * Created by florentchampigny on 19/05/2016.
 */
@RunWith(MockitoJUnitRunner.class)
public class AnnotationViewManagerTest {

    @Mock AndroidUnitTest androidUnitTest;
    @InjectMocks AnnotationViewManager manager;

    @Test
    public void testCanManagerInternal() throws Exception {
        // Given
        // When
        Object canManage = manager.canManagerInternal();
        // Then
        assertThat(canManage).isNotNull();
        assertThat(canManage).isEqualTo(RView.class);
    }

    @Test
    public void testScanned() throws Exception {
        // Given
        TestObject testObject = new TestObject();
        Field field = testObject.getClass().getDeclaredField("view1");
        // When
        manager.scanned(field);
        // Then
        assertThat(manager.fields).contains(field);
    }

    @Test
    public void testExecute() throws Exception {
        // Given
        TestObject testObject = new TestObject();
        Context context = new Application();
        manager.fields.add(testObject.getClass().getDeclaredField("view1"));
        manager.fields.add(testObject.getClass().getDeclaredField("view2"));
        // When
        manager.execute(testObject, context);
        //Then
        assertThat(testObject.view1).isNotNull();
        assertThat(testObject.view2).isNotNull();
    }

    static class TestObject {
        @RView View view1;
        @RView TextView view2;
    }
}

================================================
FILE: app/.gitignore
================================================
/build


================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    compileSdkVersion project.sdk
    buildToolsVersion project.buildTools

    defaultConfig {
        applicationId "com.github.florent37.testsample"
        minSdkVersion project.minSdk
        targetSdkVersion project.sdk
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:'+project.supportVersion
    compile 'com.android.support:support-annotations:'+project.supportVersion

    testCompile project(":androidunittest")
    testCompile 'com.google.truth:truth:0.28'
}


================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/florentchampigny/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: app/src/androidTest/java/com/github/florent37/androidunittest/ApplicationTest.java
================================================
package com.github.florent37.androidunittest;

import android.app.Application;
import android.test.ApplicationTestCase;

/**
 * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 */
public class ApplicationTest extends ApplicationTestCase<Application> {
    public ApplicationTest() {
        super(Application.class);
    }
}

================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.github.florent37.testsample"
          xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:name=".MyApplication"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

================================================
FILE: app/src/main/java/com/github/florent37/testsample/MainActivity.java
================================================
package com.github.florent37.testsample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import com.github.florent37.testsample.model.User;

public class MainActivity extends AppCompatActivity {

    TextView textView;

    boolean created = false;
    boolean resumed = false;
    boolean started = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.textView = (TextView) findViewById(R.id.textView);
        created = true;
    }

    @Override
    protected void onStart() {
        super.onStart();
        started = true;
    }

    @Override
    protected void onResume() {
        super.onResume();
        resumed = true;
    }

    public void display(User user) {
        this.textView.setText(user.getName());
    }
}


================================================
FILE: app/src/main/java/com/github/florent37/testsample/MainFragment.java
================================================
package com.github.florent37.testsample;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by florentchampigny on 08/05/2016.
 */
public class MainFragment extends Fragment{

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_main, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }
}


================================================
FILE: app/src/main/java/com/github/florent37/testsample/MainView.java
================================================
package com.github.florent37.testsample;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.FrameLayout;

import com.github.florent37.testsample.model.User;

/**
 * Created by florentchampigny on 08/05/2016.
 */
public class MainView extends FrameLayout {
    public MainView(Context context) {
        this(context, null);
    }

    public MainView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MainView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    protected void displayText(String text){

    }

    public void display(User user){
        displayText(user.getName());
    }
}


================================================
FILE: app/src/main/java/com/github/florent37/testsample/MyApplication.java
================================================
package com.github.florent37.testsample;

import android.app.Application;

/**
 * Created by florentchampigny on 07/05/2016.
 */
public class MyApplication extends Application {
}


================================================
FILE: app/src/main/java/com/github/florent37/testsample/model/User.java
================================================
package com.github.florent37.testsample.model;

/**
 * Created by florentchampigny on 08/05/2016.
 */
public class User {
    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}


================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"/>
</RelativeLayout>


================================================
FILE: app/src/main/res/layout/fragment_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

</LinearLayout>

================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>


================================================
FILE: app/src/main/res/values/dimens.xml
================================================
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>


================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">AndroidUnitTest</string>
</resources>


================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>


================================================
FILE: app/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
         (such as screen margins) for screens with more than 820dp of available width. This
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
    <dimen name="activity_horizontal_margin">64dp</dimen>
</resources>


================================================
FILE: app/src/test/java/com/github/florent37/testsample/BasicActivityTest.java
================================================
package com.github.florent37.testsample;

import android.content.Context;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RActivity;
import com.github.florent37.androidunittest.annotations.RContext;
import com.github.florent37.androidunittest.annotations.RView;
import com.github.florent37.testsample.model.User;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;

import static com.google.common.truth.Truth.assertThat;

@RunWith(CustomTestRunner.class)
public class BasicActivityTest {
    @Rule public AndroidUnitTest androidUnitTest = AndroidUnitTest.rule();

    @RContext Context context;
    @RActivity MainActivity activity;
    @RView MainView view;

    @Mock User user;

    @Test
    public void testAnnotations() throws Exception {
        assertThat(context).isNotNull();
        assertThat(activity).isNotNull();
        assertThat(view).isNotNull();
        assertThat(user).isNotNull();
    }

}


================================================
FILE: app/src/test/java/com/github/florent37/testsample/CustomTestRunner.java
================================================
package com.github.florent37.testsample;

import com.github.florent37.androidunittest.AndroidUnitTestRunner;

import org.junit.runners.model.InitializationError;

/**
 * Created by florentchampigny on 07/05/2016.
 */
public class CustomTestRunner extends AndroidUnitTestRunner {
    public CustomTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass, BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE, BuildConfig.APPLICATION_ID, TestMyApplication.class);
    }
}


================================================
FILE: app/src/test/java/com/github/florent37/testsample/MainActivityTest.java
================================================
package com.github.florent37.testsample;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RActivity;
import com.github.florent37.testsample.model.User;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.BDDMockito.given;

@RunWith(CustomTestRunner.class)
public class MainActivityTest {
    @Rule public AndroidUnitTest androidUnitTest = AndroidUnitTest.rule();

    @RActivity MainActivity activity;

    @Mock User user;

    @Test
    public void testDisplayUser() throws Exception {
        // Given
        given(user.getName()).willReturn("florent");
        // When
        activity.display(user);
        // Then
        assertThat(activity.textView.getText()).isEqualTo("florent");
    }

}


================================================
FILE: app/src/test/java/com/github/florent37/testsample/MainFragmentTest.java
================================================
package com.github.florent37.testsample;

import android.content.Context;
import android.support.v4.app.FragmentActivity;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RActivity;
import com.github.florent37.androidunittest.annotations.RContext;
import com.github.florent37.androidunittest.annotations.RFragment;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;

@RunWith(CustomTestRunner.class)
public class MainFragmentTest {
    @Rule public AndroidUnitTest androidUnitTest = AndroidUnitTest.rule();

    @RContext Context context;
    @RFragment(attached = false) MainFragment fragment;

    @Test
    public void testAnnotations() throws Exception {
        assertThat(context).isNotNull();
        assertThat(fragment).isNotNull();
    }

    @Test
    public void testAttach() throws Exception {
        // Given
        assertThat(fragment.getActivity()).isNull();

        // When
        androidUnitTest.fragment().attachToActivity(fragment);

        // Then
        assertThat(fragment.getActivity()).isNotNull();
    }

}


================================================
FILE: app/src/test/java/com/github/florent37/testsample/MainFragmentWithActivityTest.java
================================================
package com.github.florent37.testsample;

import android.content.Context;
import android.support.v4.app.FragmentActivity;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RActivity;
import com.github.florent37.androidunittest.annotations.RContext;
import com.github.florent37.androidunittest.annotations.RFragment;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import static com.google.common.truth.Truth.assertThat;

@RunWith(CustomTestRunner.class)
public class MainFragmentWithActivityTest {
    @Rule public AndroidUnitTest androidUnitTest = AndroidUnitTest.rule();

    @RContext Context context;
    @RActivity FragmentActivity fragmentActivity;
    @RFragment(attached = false, tag = "monFragment") MainFragment fragment;

    @Test
    public void testAnnotations() throws Exception {
        assertThat(context).isNotNull();
        assertThat(fragment).isNotNull();
    }

    @Test
    public void testAttach() throws Exception {
        // Given
        assertThat(fragment.getActivity()).isNull();

        // When
        androidUnitTest.fragment().attachToActivity(fragment);

        // Then
        assertThat(fragment.getActivity()).isNotNull();
        assertThat(fragmentActivity.getSupportFragmentManager().findFragmentByTag("monFragment")).isNotNull();
    }

}


================================================
FILE: app/src/test/java/com/github/florent37/testsample/MainViewTest.java
================================================
package com.github.florent37.testsample;

import android.content.Context;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RContext;
import com.github.florent37.androidunittest.annotations.RFragment;
import com.github.florent37.androidunittest.annotations.RView;
import com.github.florent37.testsample.model.User;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;

@RunWith(CustomTestRunner.class)
public class MainViewTest {
    @Rule public AndroidUnitTest androidUnitTest = AndroidUnitTest.rule();

    @RView MainView mainView;
    @Mock User user;

    @Test
    public void testDisplayUser() throws Exception {
        // Given
        given(user.getName()).willReturn("florent");
        // When
        mainView.display(user);
        // Then
        verify(mainView).displayText("florent");
    }


}


================================================
FILE: app/src/test/java/com/github/florent37/testsample/StateActivityTest.java
================================================
package com.github.florent37.testsample;

import com.github.florent37.androidunittest.AndroidUnitTest;
import com.github.florent37.androidunittest.annotations.RActivity;
import com.github.florent37.androidunittest.states.ActivityState;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import static com.google.common.truth.Truth.assertThat;

@RunWith(CustomTestRunner.class)
public class StateActivityTest {
    @Rule public AndroidUnitTest androidUnitTest = AndroidUnitTest.rule();

    @RActivity(state = ActivityState.STARTED) MainActivity activity;

    @Test
    public void testAnnotations() throws Exception {
        assertThat(activity.created).isTrue();
        assertThat(activity.started).isTrue();
        assertThat(activity.resumed).isFalse();
    }

}


================================================
FILE: app/src/test/java/com/github/florent37/testsample/TestMyApplication.java
================================================
package com.github.florent37.testsample;

/**
 * Created by florentchampigny on 07/05/2016.
 */
public class TestMyApplication extends MyApplication {
}


================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
        classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1"
        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

ext {
    sdk = 23
    buildTools = "23.0.3"
    minSdk = 10
    libraryVersion = "1.0.1"
    supportVersion = "23.3.0"
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


================================================
FILE: gradle/bintray-android-v1.gradle
================================================
apply plugin: 'com.jfrog.bintray'

version = libraryVersion

task sourcesJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
    classifier = 'sources'
}

task javadoc(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}

task javadocJar(type: Jar, dependsOn: javadoc) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}
artifacts {
    archives javadocJar
    archives sourcesJar
}

// Bintray
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())

bintray {
    user = properties.getProperty("bintray.user")
    key = properties.getProperty("bintray.apikey")

    configurations = ['archives']
    pkg {
        repo = bintrayRepo
        name = bintrayName
        desc = libraryDescription
        userOrg = orgName
        websiteUrl = siteUrl
        vcsUrl = gitUrl
        licenses = allLicenses
        publish = true
        publicDownloadNumbers = true
        version {
            desc = libraryDescription
            gpg {
                sign = true //Determines whether to GPG sign the files. The default is false
                passphrase = properties.getProperty("bintray.gpg.password")
                //Optional. The passphrase for GPG signing'
            }
        }
    }
}

================================================
FILE: gradle/bintray-java-v1.gradle
================================================
apply plugin: 'com.jfrog.bintray'

version = libraryVersion

task sourcesJar(type: Jar) {
    from sourceSets.main.allSource
    classifier = 'sources'
}

task javadocJar(type: Jar, dependsOn: javadoc) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}
artifacts {
    archives javadocJar
    archives sourcesJar
}

// Bintray
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())

bintray {
    user = properties.getProperty("bintray.user")
    key = properties.getProperty("bintray.apikey")

    configurations = ['archives']
    pkg {
        repo = bintrayRepo
        name = bintrayName
        desc = libraryDescription
        userOrg = orgName
        websiteUrl = siteUrl
        vcsUrl = gitUrl
        licenses = ['Apache-2.0']
        publish = true
        publicDownloadNumbers = true
        version {
            desc = libraryDescription
            gpg {
                sign = true //Determines whether to GPG sign the files. The default is false
                passphrase = properties.getProperty("bintray.gpg.password")
                //Optional. The passphrase for GPG signing'
            }
        }
    }
}

//from https://github.com/workarounds/bundler/blob/master/gradle/bintray-java-v1.gradle

================================================
FILE: gradle/install-v1.gradle
================================================
apply plugin: 'com.github.dcendents.android-maven'

group = publishedGroupId                               // Maven Group ID for the artifact

install {
    repositories.mavenInstaller {
        // This generates POM.xml with proper parameters
        pom {
            project {
                packaging 'aar'
                groupId publishedGroupId
                artifactId artifact

                // Add your description here
                name libraryName
                description libraryDescription
                url siteUrl

                // Set your license
                licenses {
                    license {
                        name licenseName
                        url licenseUrl
                    }
                }
                developers {
                    developer {
                        id developerId
                        name developerName
                        email developerEmail
                    }
                }
                scm {
                    connection gitUrl
                    developerConnection gitUrl
                    url siteUrl

                }
            }
        }
    }
}

//from https://github.com/workarounds/bundler/blob/master/gradle/install-v1.gradle

================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip


================================================
FILE: gradle.properties
================================================
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

================================================
FILE: gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: settings.gradle
================================================
include ':app', ':androidunittest'
Download .txt
gitextract_jyd7hg8s/

├── .gitignore
├── LICENSE
├── README.md
├── androidunittest/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── github/
│       │               └── florent37/
│       │                   └── androidunittest/
│       │                       └── ApplicationTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── github/
│       │   │           └── florent37/
│       │   │               └── androidunittest/
│       │   │                   ├── AndroidUnitTest.java
│       │   │                   ├── AndroidUnitTestAnnotations.java
│       │   │                   ├── AndroidUnitTestRunner.java
│       │   │                   ├── annotations/
│       │   │                   │   ├── RActivity.java
│       │   │                   │   ├── RContext.java
│       │   │                   │   ├── RFragment.java
│       │   │                   │   └── RView.java
│       │   │                   ├── controllers/
│       │   │                   │   ├── ControllerActivity.java
│       │   │                   │   └── ControllerFragment.java
│       │   │                   ├── managers/
│       │   │                   │   ├── AbstractAnnotationManager.java
│       │   │                   │   ├── AnnotationActivityManager.java
│       │   │                   │   ├── AnnotationContextManager.java
│       │   │                   │   ├── AnnotationFragmentManager.java
│       │   │                   │   └── AnnotationViewManager.java
│       │   │                   └── states/
│       │   │                       └── ActivityState.java
│       │   └── res/
│       │       └── values/
│       │           └── strings.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── github/
│                       └── florent37/
│                           └── androidunittest/
│                               └── managers/
│                                   ├── AnnotationActivityManagerTest.java
│                                   ├── AnnotationContextManagerTest.java
│                                   ├── AnnotationFragmentManagerTest.java
│                                   └── AnnotationViewManagerTest.java
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── github/
│       │               └── florent37/
│       │                   └── androidunittest/
│       │                       └── ApplicationTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── github/
│       │   │           └── florent37/
│       │   │               └── testsample/
│       │   │                   ├── MainActivity.java
│       │   │                   ├── MainFragment.java
│       │   │                   ├── MainView.java
│       │   │                   ├── MyApplication.java
│       │   │                   └── model/
│       │   │                       └── User.java
│       │   └── res/
│       │       ├── layout/
│       │       │   ├── activity_main.xml
│       │       │   └── fragment_main.xml
│       │       ├── values/
│       │       │   ├── colors.xml
│       │       │   ├── dimens.xml
│       │       │   ├── strings.xml
│       │       │   └── styles.xml
│       │       └── values-w820dp/
│       │           └── dimens.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── github/
│                       └── florent37/
│                           └── testsample/
│                               ├── BasicActivityTest.java
│                               ├── CustomTestRunner.java
│                               ├── MainActivityTest.java
│                               ├── MainFragmentTest.java
│                               ├── MainFragmentWithActivityTest.java
│                               ├── MainViewTest.java
│                               ├── StateActivityTest.java
│                               └── TestMyApplication.java
├── build.gradle
├── gradle/
│   ├── bintray-android-v1.gradle
│   ├── bintray-java-v1.gradle
│   ├── install-v1.gradle
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
Download .txt
SYMBOL INDEX (159 symbols across 30 files)

FILE: androidunittest/src/androidTest/java/com/github/florent37/androidunittest/ApplicationTest.java
  class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
    method ApplicationTest (line 10) | public ApplicationTest() {

FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/AndroidUnitTest.java
  class AndroidUnitTest (line 18) | public class AndroidUnitTest implements MethodRule {
    method AndroidUnitTest (line 25) | protected AndroidUnitTest() {
    method rule (line 31) | public static AndroidUnitTest rule() {
    method apply (line 35) | @Override
    method getActivityController (line 48) | @Nullable
    method setActivityController (line 53) | public void setActivityController(@Nullable ActivityController activit...
    method getAndroidUnitTestAnnotations (line 57) | public AndroidUnitTestAnnotations getAndroidUnitTestAnnotations() {
    method activity (line 61) | public ControllerActivity activity() {
    method fragment (line 65) | public ControllerFragment fragment() {

FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/AndroidUnitTestAnnotations.java
  class AndroidUnitTestAnnotations (line 20) | public class AndroidUnitTestAnnotations {
    method AndroidUnitTestAnnotations (line 31) | private AndroidUnitTestAnnotations() {
    method AndroidUnitTestAnnotations (line 35) | public AndroidUnitTestAnnotations(AndroidUnitTest androidUnitTest) {
    method init (line 42) | public AndroidUnitTestAnnotations init(Object target) {
    method updateActivity (line 55) | public void updateActivity() {
    method addToActivity (line 59) | public void addToActivity(@NonNull Fragment fragment) {
    method removeFromActivity (line 63) | public void removeFromActivity(@NonNull Fragment fragment) {
    method instantiate (line 71) | private void instantiate() {
    method scan (line 86) | private void scan() {
    method execute (line 99) | private void execute() {

FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/AndroidUnitTestRunner.java
  class AndroidUnitTestRunner (line 18) | public class AndroidUnitTestRunner extends RobolectricTestRunner {
    method AndroidUnitTestRunner (line 37) | public AndroidUnitTestRunner(Class<?> testClass, @NonNull String flavo...
    method getPathManifest (line 45) | public String getPathManifest() {
    method getPathAssets (line 53) | public String getPathAssets() {
    method getPathResources (line 63) | public String getPathResources() {
    method createClassLoaderConfig (line 73) | @Override
    method getAppManifest (line 79) | @Override
    method pickSdkVersion (line 101) | @Override
    method createShadowMap (line 107) | @Override
    method overwriteConfig (line 114) | protected Config.Implementation overwriteConfig(Config config, String ...

FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/controllers/ControllerActivity.java
  class ControllerActivity (line 17) | public class ControllerActivity {
    method ControllerActivity (line 21) | public ControllerActivity(AndroidUnitTest androidUnitTest) {
    method get (line 25) | @Nullable
    method getActivityController (line 33) | @Nullable
    method createAndInitActivity (line 41) | public Activity createAndInitActivity(Class activityClass, @Nullable R...
    method resume (line 52) | public ControllerActivity resume() {
    method create (line 60) | public ControllerActivity create() {
    method start (line 68) | public ControllerActivity start() {
    method pause (line 76) | public ControllerActivity pause() {
    method stop (line 84) | public ControllerActivity stop() {
    method destroy (line 92) | public ControllerActivity destroy() {
    method setActivityState (line 100) | public ControllerActivity setActivityState(ActivityState activityState) {
    method setActivityState (line 107) | public ControllerActivity setActivityState(ActivityController activity...
    method applyState (line 119) | private void applyState(ActivityState state,

FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/controllers/ControllerFragment.java
  class ControllerFragment (line 10) | public class ControllerFragment {
    method ControllerFragment (line 12) | public ControllerFragment(AndroidUnitTest androidUnitTest) {
    method attachToActivity (line 16) | public ControllerFragment attachToActivity(Fragment fragment){
    method removeFromActivity (line 24) | public ControllerFragment removeFromActivity(Fragment fragment){

FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AbstractAnnotationManager.java
  class AbstractAnnotationManager (line 14) | public abstract class AbstractAnnotationManager {
    method AbstractAnnotationManager (line 17) | private AbstractAnnotationManager() {
    method AbstractAnnotationManager (line 21) | public AbstractAnnotationManager(AndroidUnitTest parent) {
    method canManage (line 27) | public final boolean canManage(@NonNull Field field) {
    method canManagerInternal (line 31) | @NonNull
    method scanned (line 40) | public abstract void scanned(@NonNull Field field);
    method execute (line 49) | public abstract void execute(@NonNull Object object,
    method getAndroidUnitTest (line 52) | @NonNull

FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AnnotationActivityManager.java
  class AnnotationActivityManager (line 20) | public class AnnotationActivityManager extends AbstractAnnotationManager {
    method AnnotationActivityManager (line 24) | public AnnotationActivityManager(AndroidUnitTest parent) {
    method scanned (line 33) | @Override
    method execute (line 38) | @Override
    method getScanned (line 47) | public Field getScanned() {
    method createAndInitActivity (line 51) | public void createAndInitActivity(@Nullable Object target, Class activ...
    method updateActivity (line 58) | public void updateActivity(Object target) {
    method canManagerInternal (line 63) | @NonNull

FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AnnotationContextManager.java
  class AnnotationContextManager (line 19) | public class AnnotationContextManager extends AbstractAnnotationManager {
    method AnnotationContextManager (line 23) | public AnnotationContextManager(AndroidUnitTest parent) {
    method scanned (line 27) | @Override
    method execute (line 32) | @Override
    method canManagerInternal (line 41) | @NonNull

FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AnnotationFragmentManager.java
  class AnnotationFragmentManager (line 26) | public class AnnotationFragmentManager extends AbstractAnnotationManager {
    method AnnotationFragmentManager (line 29) | public AnnotationFragmentManager(AndroidUnitTest parent) {
    method addToActivity (line 35) | public static void addToActivity(Activity activity, Fragment fragment,...
    method removeFromActivity (line 44) | public static void removeFromActivity(Activity activity, Fragment frag...
    method scanned (line 53) | @Override
    method execute (line 58) | @Override
    method initFragment (line 65) | public void initFragment(@NonNull Object target, @NonNull Field fragme...
    method addToActivity (line 95) | public void addToActivity(@NonNull Object target, Fragment fragment) {
    method removeFromActivity (line 118) | public void removeFromActivity(Fragment fragment) {
    method canManagerInternal (line 122) | @NonNull
    method getActivity (line 128) | private Activity getActivity() {

FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AnnotationViewManager.java
  class AnnotationViewManager (line 22) | public class AnnotationViewManager extends AbstractAnnotationManager {
    method AnnotationViewManager (line 26) | public AnnotationViewManager(AndroidUnitTest androidUnitTest) {
    method scanned (line 32) | @Override
    method execute (line 37) | @Override
    method canManagerInternal (line 44) | @NonNull
    method initView (line 50) | private void initView(@NonNull Object target, @NonNull Context context...

FILE: androidunittest/src/main/java/com/github/florent37/androidunittest/states/ActivityState.java
  type ActivityState (line 10) | public enum ActivityState {
    method ActivityState (line 22) | ActivityState(ActivityState next) {
    method next (line 26) | public ActivityState next() {
    method isLowerOrEquals (line 39) | public boolean isLowerOrEquals(@NonNull ActivityState state) {

FILE: androidunittest/src/test/java/com/github/florent37/androidunittest/managers/AnnotationActivityManagerTest.java
  class AnnotationActivityManagerTest (line 35) | @RunWith(RobolectricTestRunner.class)
    method setUp (line 46) | @Before
    method testCanManagerInternal (line 52) | @Test
    method testScanned (line 62) | @Test
    method testExecute (line 73) | @Test
    method testExecuteState (line 87) | @Test
    class TestObject (line 103) | static class TestObject {
    class TestObjectState (line 107) | static class TestObjectState {
    class TestActivity (line 111) | static class TestActivity extends Activity {
      method onCreate (line 116) | @Override
      method onStart (line 122) | @Override
      method onResume (line 128) | @Override

FILE: androidunittest/src/test/java/com/github/florent37/androidunittest/managers/AnnotationContextManagerTest.java
  class AnnotationContextManagerTest (line 22) | @RunWith(MockitoJUnitRunner.class)
    method testCanManagerInternal (line 28) | @Test
    method testScanned (line 38) | @Test
    method testExecute (line 49) | @Test
    class TestObject (line 61) | static class TestObject {

FILE: androidunittest/src/test/java/com/github/florent37/androidunittest/managers/AnnotationFragmentManagerTest.java
  class AnnotationFragmentManagerTest (line 28) | @RunWith(RobolectricTestRunner.class)
    method setUp (line 37) | @Before
    method testCanManagerInternal (line 43) | @Test
    method testScanned (line 53) | @Test
    method testExecute (line 64) | @Test
    method testAddToActivity (line 78) | @Test
    method testRemoveFromActivity (line 89) | @Test
    method testAddToActivityWithTag (line 101) | @Test
    class TestObject (line 114) | static class TestObject {

FILE: androidunittest/src/test/java/com/github/florent37/androidunittest/managers/AnnotationViewManagerTest.java
  class AnnotationViewManagerTest (line 24) | @RunWith(MockitoJUnitRunner.class)
    method testCanManagerInternal (line 30) | @Test
    method testScanned (line 40) | @Test
    method testExecute (line 51) | @Test
    class TestObject (line 65) | static class TestObject {

FILE: app/src/androidTest/java/com/github/florent37/androidunittest/ApplicationTest.java
  class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
    method ApplicationTest (line 10) | public ApplicationTest() {

FILE: app/src/main/java/com/github/florent37/testsample/MainActivity.java
  class MainActivity (line 9) | public class MainActivity extends AppCompatActivity {
    method onCreate (line 17) | @Override
    method onStart (line 26) | @Override
    method onResume (line 32) | @Override
    method display (line 38) | public void display(User user) {

FILE: app/src/main/java/com/github/florent37/testsample/MainFragment.java
  class MainFragment (line 13) | public class MainFragment extends Fragment{
    method onCreateView (line 15) | @Nullable
    method onViewCreated (line 21) | @Override

FILE: app/src/main/java/com/github/florent37/testsample/MainView.java
  class MainView (line 12) | public class MainView extends FrameLayout {
    method MainView (line 13) | public MainView(Context context) {
    method MainView (line 17) | public MainView(Context context, AttributeSet attrs) {
    method MainView (line 21) | public MainView(Context context, AttributeSet attrs, int defStyleAttr) {
    method displayText (line 25) | protected void displayText(String text){
    method display (line 29) | public void display(User user){

FILE: app/src/main/java/com/github/florent37/testsample/MyApplication.java
  class MyApplication (line 8) | public class MyApplication extends Application {

FILE: app/src/main/java/com/github/florent37/testsample/model/User.java
  class User (line 6) | public class User {
    method getName (line 9) | public String getName() {
    method setName (line 13) | public void setName(String name) {

FILE: app/src/test/java/com/github/florent37/testsample/BasicActivityTest.java
  class BasicActivityTest (line 18) | @RunWith(CustomTestRunner.class)
    method testAnnotations (line 28) | @Test

FILE: app/src/test/java/com/github/florent37/testsample/CustomTestRunner.java
  class CustomTestRunner (line 10) | public class CustomTestRunner extends AndroidUnitTestRunner {
    method CustomTestRunner (line 11) | public CustomTestRunner(Class<?> testClass) throws InitializationError {

FILE: app/src/test/java/com/github/florent37/testsample/MainActivityTest.java
  class MainActivityTest (line 15) | @RunWith(CustomTestRunner.class)
    method testDisplayUser (line 23) | @Test

FILE: app/src/test/java/com/github/florent37/testsample/MainFragmentTest.java
  class MainFragmentTest (line 18) | @RunWith(CustomTestRunner.class)
    method testAnnotations (line 25) | @Test
    method testAttach (line 31) | @Test

FILE: app/src/test/java/com/github/florent37/testsample/MainFragmentWithActivityTest.java
  class MainFragmentWithActivityTest (line 17) | @RunWith(CustomTestRunner.class)
    method testAnnotations (line 25) | @Test
    method testAttach (line 31) | @Test

FILE: app/src/test/java/com/github/florent37/testsample/MainViewTest.java
  class MainViewTest (line 20) | @RunWith(CustomTestRunner.class)
    method testDisplayUser (line 27) | @Test

FILE: app/src/test/java/com/github/florent37/testsample/StateActivityTest.java
  class StateActivityTest (line 13) | @RunWith(CustomTestRunner.class)
    method testAnnotations (line 19) | @Test

FILE: app/src/test/java/com/github/florent37/testsample/TestMyApplication.java
  class TestMyApplication (line 6) | public class TestMyApplication extends MyApplication {
Condensed preview — 63 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (98K chars).
[
  {
    "path": ".gitignore",
    "chars": 425,
    "preview": "# Built application files\n*.apk\n*.ap_\n\n# Files for the Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbi"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 5595,
    "preview": "# Android Unit Test\n\nSave time & clear your unit tests on Android ! \n\nUse annotations to inject Context, Activities, Fra"
  },
  {
    "path": "androidunittest/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "androidunittest/build.gradle",
    "chars": 1546,
    "preview": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion project.sdk\n    buildToolsVersion project.buildTool"
  },
  {
    "path": "androidunittest/proguard-rules.pro",
    "chars": 666,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "androidunittest/src/androidTest/java/com/github/florent37/androidunittest/ApplicationTest.java",
    "chars": 367,
    "preview": "package com.github.florent37.androidunittest;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n"
  },
  {
    "path": "androidunittest/src/main/AndroidManifest.xml",
    "chars": 299,
    "preview": "<manifest package=\"com.github.florent37.androidunittest\"\n          xmlns:android=\"http://schemas.android.com/apk/res/and"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/AndroidUnitTest.java",
    "chars": 2138,
    "preview": "package com.github.florent37.androidunittest;\n\nimport android.support.annotation.Nullable;\n\nimport com.github.florent37."
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/AndroidUnitTestAnnotations.java",
    "chars": 2987,
    "preview": "package com.github.florent37.androidunittest;\n\nimport android.content.Context;\nimport android.support.annotation.NonNull"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/AndroidUnitTestRunner.java",
    "chars": 4569,
    "preview": "package com.github.florent37.androidunittest;\n\nimport android.app.Application;\nimport android.os.Build;\nimport android.s"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/annotations/RActivity.java",
    "chars": 390,
    "preview": "package com.github.florent37.androidunittest.annotations;\n\nimport com.github.florent37.androidunittest.states.ActivitySt"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/annotations/RContext.java",
    "chars": 265,
    "preview": "package com.github.florent37.androidunittest.annotations;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annot"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/annotations/RFragment.java",
    "chars": 332,
    "preview": "package com.github.florent37.androidunittest.annotations;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annot"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/annotations/RView.java",
    "chars": 299,
    "preview": "package com.github.florent37.androidunittest.annotations;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annot"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/controllers/ControllerActivity.java",
    "chars": 4758,
    "preview": "package com.github.florent37.androidunittest.controllers;\n\nimport android.app.Activity;\nimport android.support.annotatio"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/controllers/ControllerFragment.java",
    "chars": 842,
    "preview": "package com.github.florent37.androidunittest.controllers;\n\nimport android.support.v4.app.Fragment;\n\nimport com.github.fl"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AbstractAnnotationManager.java",
    "chars": 1470,
    "preview": "package com.github.florent37.androidunittest.managers;\n\nimport android.content.Context;\nimport android.support.annotatio"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AnnotationActivityManager.java",
    "chars": 2277,
    "preview": "package com.github.florent37.androidunittest.managers;\n\nimport android.app.Activity;\nimport android.content.Context;\nimp"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AnnotationContextManager.java",
    "chars": 1267,
    "preview": "package com.github.florent37.androidunittest.managers;\n\nimport android.content.Context;\nimport android.support.annotatio"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AnnotationFragmentManager.java",
    "chars": 4797,
    "preview": "package com.github.florent37.androidunittest.managers;\n\nimport android.app.Activity;\nimport android.content.Context;\nimp"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/managers/AnnotationViewManager.java",
    "chars": 1717,
    "preview": "package com.github.florent37.androidunittest.managers;\n\nimport android.content.Context;\nimport android.support.annotatio"
  },
  {
    "path": "androidunittest/src/main/java/com/github/florent37/androidunittest/states/ActivityState.java",
    "chars": 1242,
    "preview": "package com.github.florent37.androidunittest.states;\n\nimport android.support.annotation.NonNull;\n\n/**\n * Created by kevi"
  },
  {
    "path": "androidunittest/src/main/res/values/strings.xml",
    "chars": 78,
    "preview": "<resources>\n    <string name=\"app_name\">AndroidUnitTest</string>\n</resources>\n"
  },
  {
    "path": "androidunittest/src/test/java/com/github/florent37/androidunittest/managers/AnnotationActivityManagerTest.java",
    "chars": 4217,
    "preview": "package com.github.florent37.androidunittest.managers;\n\nimport android.app.Activity;\nimport android.app.Application;\nimp"
  },
  {
    "path": "androidunittest/src/test/java/com/github/florent37/androidunittest/managers/AnnotationContextManagerTest.java",
    "chars": 1802,
    "preview": "package com.github.florent37.androidunittest.managers;\n\nimport android.app.Application;\nimport android.content.Context;\n"
  },
  {
    "path": "androidunittest/src/test/java/com/github/florent37/androidunittest/managers/AnnotationFragmentManagerTest.java",
    "chars": 3701,
    "preview": "package com.github.florent37.androidunittest.managers;\n\nimport android.app.Application;\nimport android.content.Context;\n"
  },
  {
    "path": "androidunittest/src/test/java/com/github/florent37/androidunittest/managers/AnnotationViewManagerTest.java",
    "chars": 1982,
    "preview": "package com.github.florent37.androidunittest.managers;\n\nimport android.app.Application;\nimport android.content.Context;\n"
  },
  {
    "path": "app/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "chars": 823,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion project.sdk\n    buildToolsVersion project.build"
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 666,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "app/src/androidTest/java/com/github/florent37/androidunittest/ApplicationTest.java",
    "chars": 367,
    "preview": "package com.github.florent37.androidunittest;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 713,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest package=\"com.github.florent37.testsample\"\n          xmlns:android=\"http"
  },
  {
    "path": "app/src/main/java/com/github/florent37/testsample/MainActivity.java",
    "chars": 924,
    "preview": "package com.github.florent37.testsample;\n\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimp"
  },
  {
    "path": "app/src/main/java/com/github/florent37/testsample/MainFragment.java",
    "chars": 736,
    "preview": "package com.github.florent37.testsample;\n\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport a"
  },
  {
    "path": "app/src/main/java/com/github/florent37/testsample/MainView.java",
    "chars": 731,
    "preview": "package com.github.florent37.testsample;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport andro"
  },
  {
    "path": "app/src/main/java/com/github/florent37/testsample/MyApplication.java",
    "chars": 180,
    "preview": "package com.github.florent37.testsample;\n\nimport android.app.Application;\n\n/**\n * Created by florentchampigny on 07/05/2"
  },
  {
    "path": "app/src/main/java/com/github/florent37/testsample/model/User.java",
    "chars": 271,
    "preview": "package com.github.florent37.testsample.model;\n\n/**\n * Created by florentchampigny on 08/05/2016.\n */\npublic class User "
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "chars": 684,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  "
  },
  {
    "path": "app/src/main/res/layout/fragment_main.xml",
    "chars": 275,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        "
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "chars": 208,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"color"
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "chars": 211,
    "preview": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "chars": 78,
    "preview": "<resources>\n    <string name=\"app_name\">AndroidUnitTest</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "chars": 383,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
  },
  {
    "path": "app/src/main/res/values-w820dp/dimens.xml",
    "chars": 358,
    "preview": "<resources>\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n         (such as s"
  },
  {
    "path": "app/src/test/java/com/github/florent37/testsample/BasicActivityTest.java",
    "chars": 1037,
    "preview": "package com.github.florent37.testsample;\n\nimport android.content.Context;\n\nimport com.github.florent37.androidunittest.A"
  },
  {
    "path": "app/src/test/java/com/github/florent37/testsample/CustomTestRunner.java",
    "chars": 487,
    "preview": "package com.github.florent37.testsample;\n\nimport com.github.florent37.androidunittest.AndroidUnitTestRunner;\n\nimport org"
  },
  {
    "path": "app/src/test/java/com/github/florent37/testsample/MainActivityTest.java",
    "chars": 906,
    "preview": "package com.github.florent37.testsample;\n\nimport com.github.florent37.androidunittest.AndroidUnitTest;\nimport com.github"
  },
  {
    "path": "app/src/test/java/com/github/florent37/testsample/MainFragmentTest.java",
    "chars": 1233,
    "preview": "package com.github.florent37.testsample;\n\nimport android.content.Context;\nimport android.support.v4.app.FragmentActivity"
  },
  {
    "path": "app/src/test/java/com/github/florent37/testsample/MainFragmentWithActivityTest.java",
    "chars": 1388,
    "preview": "package com.github.florent37.testsample;\n\nimport android.content.Context;\nimport android.support.v4.app.FragmentActivity"
  },
  {
    "path": "app/src/test/java/com/github/florent37/testsample/MainViewTest.java",
    "chars": 1077,
    "preview": "package com.github.florent37.testsample;\n\nimport android.content.Context;\n\nimport com.github.florent37.androidunittest.A"
  },
  {
    "path": "app/src/test/java/com/github/florent37/testsample/StateActivityTest.java",
    "chars": 800,
    "preview": "package com.github.florent37.testsample;\n\nimport com.github.florent37.androidunittest.AndroidUnitTest;\nimport com.github"
  },
  {
    "path": "app/src/test/java/com/github/florent37/testsample/TestMyApplication.java",
    "chars": 153,
    "preview": "package com.github.florent37.testsample;\n\n/**\n * Created by florentchampigny on 07/05/2016.\n */\npublic class TestMyAppli"
  },
  {
    "path": "build.gradle",
    "chars": 839,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    r"
  },
  {
    "path": "gradle/bintray-android-v1.gradle",
    "chars": 1390,
    "preview": "apply plugin: 'com.jfrog.bintray'\n\nversion = libraryVersion\n\ntask sourcesJar(type: Jar) {\n    from android.sourceSets.ma"
  },
  {
    "path": "gradle/bintray-java-v1.gradle",
    "chars": 1304,
    "preview": "apply plugin: 'com.jfrog.bintray'\n\nversion = libraryVersion\n\ntask sourcesJar(type: Jar) {\n    from sourceSets.main.allSo"
  },
  {
    "path": "gradle/install-v1.gradle",
    "chars": 1258,
    "preview": "apply plugin: 'com.github.dcendents.android-maven'\n\ngroup = publishedGroupId                               // Maven Grou"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 231,
    "preview": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradle.properties",
    "chars": 855,
    "preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
  },
  {
    "path": "gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2404,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "settings.gradle",
    "chars": 35,
    "preview": "include ':app', ':androidunittest'\n"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the florent37/AndroidUnitTest GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 63 files (87.3 KB), approximately 21.8k tokens, and a symbol index with 159 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!