Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for Activity and Fragment coming from the support libraries: #275

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -73,8 +73,22 @@ final class ErrorProneCLIFlagsConfig extends AbstractConfig {
"android.app.Service.onCreate",
"android.app.Activity.onCreate",
"android.app.Fragment.onCreate",
"android.app.Fragment.onAttach",
"android.app.Fragment.onCreateView",
"android.app.Application.onCreate",
"javax.annotation.processing.Processor.init");
"javax.annotation.processing.Processor.init",
// Support Library v4 - can be removed once AndroidX becomes more popular
"android.support.v4.app.ActivityCompat.onCreate",
"android.support.v4.app.Fragment.onCreate",
"android.support.v4.app.Fragment.onAttach",
"android.support.v4.app.Fragment.onCreateView",
// Support Library v4 - can be removed once AndroidX becomes more popular
"androidx.core.app.ActivityCompat.onCreate",
"androidx.fragment.app.Fragment.onCreate",
"androidx.fragment.app.Fragment.onAttach",
"androidx.fragment.app.Fragment.onCreateView",
// Multidex app
"android.support.multidex.Application.onCreate");

static final ImmutableSet<String> DEFAULT_INITIALIZER_ANNOT =
ImmutableSet.of(
Expand Down
211 changes: 211 additions & 0 deletions nullaway/src/test/java/com/uber/nullaway/NullAwayAndroidTest.java
@@ -0,0 +1,211 @@
package com.uber.nullaway;

import com.google.errorprone.CompilationTestHelper;
import com.sun.tools.javac.main.Main;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for {@link com.uber.nullaway.NullAway}. */
@RunWith(JUnit4.class)
@SuppressWarnings("CheckTestExtendsBaseClass")
public class NullAwayAndroidTest {
@Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder();

private CompilationTestHelper compilationHelper;

@Before
public void setup() {
compilationHelper = CompilationTestHelper.newInstance(NullAway.class, getClass());
compilationHelper.setArgs(
Arrays.asList(
"-d",
temporaryFolder.getRoot().getAbsolutePath(),
"-XepOpt:NullAway:KnownInitializers="
yanislavm marked this conversation as resolved.
Show resolved Hide resolved
+ "com.uber.nullaway.testdata.CheckFieldInitNegativeCases.Super.doInit,"
+ "com.uber.nullaway.testdata.CheckFieldInitNegativeCases"
+ ".SuperInterface.doInit2",
"-XepOpt:NullAway:AnnotatedPackages=com.uber,com.ubercab,io.reactivex",
// We give the following in Regexp format to test that support
"-XepOpt:NullAway:UnannotatedSubPackages=com.uber.nullaway.[a-zA-Z0-9.]+.unannotated",
"-XepOpt:NullAway:ExcludedClasses="
+ "com.uber.nullaway.testdata.Shape_Stuff,"
+ "com.uber.nullaway.testdata.excluded",
"-XepOpt:NullAway:ExcludedClassAnnotations=com.uber.nullaway.testdata.TestAnnot",
"-XepOpt:NullAway:CastToNonNullMethod=com.uber.nullaway.testdata.Util.castToNonNull",
"-XepOpt:NullAway:ExternalInitAnnotations=com.uber.ExternalInit",
"-XepOpt:NullAway:ExcludedFieldAnnotations=com.uber.ExternalFieldInit"));
}

// Core Fragment tests

@Test
public void coreFragmentSuccess() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/core/Fragment.java")
.addSourceFile("android-success/CoreFragment.java")
.doTest();
}

@Test(expected = AssertionError.class)
public void coreFragmentMissingOnAttachError() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/core/Fragment.java")
.addSourceFile("android-error/CoreFragmentWithoutOnAttach.java")
yanislavm marked this conversation as resolved.
Show resolved Hide resolved
.expectResult(Main.Result.ERROR)
.doTest();
}

@Test(expected = AssertionError.class)
public void coreFragmentMissingOnCreateError() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/core/Fragment.java")
.addSourceFile("android-error/CoreFragmentWithoutOnCreate.java")
.expectResult(Main.Result.ERROR)
.doTest();
}

@Test(expected = AssertionError.class)
public void coreFragmentMissingOnCreateViewError() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/core/Fragment.java")
.addSourceFile("android-error/CoreFragmentWithoutOnCreateView.java")
.expectResult(Main.Result.ERROR)
.doTest();
}

// AndroidX Library Fragment
@Test
public void androidxFragmentSuccess() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/androidx/Fragment.java")
.addSourceFile("android-success/AndroidxFragment.java")
.doTest();
}

@Test(expected = AssertionError.class)
public void androidxFragmentMissingOnAttachError() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/core/Fragment.java")
.addSourceFile("android-error/AndroidxFragmentWithoutOnAttach.java")
.expectResult(Main.Result.ERROR)
.doTest();
}

@Test(expected = AssertionError.class)
public void androidxFragmentMissingOnCreateError() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/core/Fragment.java")
.addSourceFile("android-error/AndroidxFragmentWithoutOnCreate.java")
.expectResult(Main.Result.ERROR)
.doTest();
}

@Test(expected = AssertionError.class)
public void androidxFragmentMissingOnCreateViewError() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/core/Fragment.java")
.addSourceFile("android-error/AndroidxFragmentWithoutOnCreateView.java")
.expectResult(Main.Result.ERROR)
.doTest();
}

// Android support library Fragment

@Test
public void supportLibFragmentSuccess() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/supportlib/Fragment.java")
.addSourceFile("android-success/SupportLibraryFragment.java")
.doTest();
}

@Test(expected = AssertionError.class)
public void supportLibFragmentMissingOnAttachError() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/core/Fragment.java")
.addSourceFile("android-error/SupportLibraryFragmentWithoutOnAttach.java")
.expectResult(Main.Result.ERROR)
.doTest();
}

@Test(expected = AssertionError.class)
public void supportLibFragmentMissingOnCreateError() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/core/Fragment.java")
.addSourceFile("android-error/SupportLibraryFragmentWithoutOnCreate.java")
.expectResult(Main.Result.ERROR)
.doTest();
}

@Test(expected = AssertionError.class)
public void supportLibFragmentMissingOnCreateViewError() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/core/Fragment.java")
.addSourceFile("android-error/SupportLibraryFragmentWithoutOnCreateView.java")
.expectResult(Main.Result.ERROR)
.doTest();
}

// Core Activity

@Test
public void coreActivitySuccess() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/core/Activity.java")
.addSourceFile("android-success/CoreActivity.java")
.doTest();
}

// Support Library Activity

@Test
public void supportLibActivitySuccess() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/supportlib/ActivityCompat.java")
.addSourceFile("android-success/SupportLibActivityCompat.java")
.doTest();
}

// AndroidX Library Activity

@Test
public void androidxActivitySuccess() {
initialiseAndroidCoreClasses();
compilationHelper
.addSourceFile("androidstubs/androidx/ActivityCompat.java")
.addSourceFile("android-success/AndroidxActivityCompat.java")
.doTest();
}

/** Initialises the default android classes that are commonly used. */
private void initialiseAndroidCoreClasses() {
compilationHelper
.addSourceFile("androidstubs/annotations/Nullable.java")
.addSourceFile("androidstubs/annotations/NonNull.java")
.addSourceFile("androidstubs/core/Context.java")
.addSourceFile("androidstubs/core/Bundle.java")
.addSourceFile("androidstubs/core/LayoutInflater.java")
.addSourceFile("androidstubs/core/PersistableBundle.java")
.addSourceFile("androidstubs/core/View.java")
.addSourceFile("androidstubs/core/ViewGroup.java");
}
}
@@ -0,0 +1,32 @@
package com.uber.myapplication;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;

public class AndroidxFragmentWithoutOnAttach extends Fragment {

@NonNull private Object mOnCreateInitialisedField;
yanislavm marked this conversation as resolved.
Show resolved Hide resolved
@NonNull private Object mOnCreateViewInitialisedField;
@NonNull private Object mOnAttachInitialisedField;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mOnCreateInitialisedField = new Object();
}

@Nullable
@Override
public View onCreateView(
@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
mOnCreateViewInitialisedField = new Object();
return super.onCreateView(inflater, container, savedInstanceState);
}
}
@@ -0,0 +1,33 @@
package com.uber.myapplication;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;

public class AndroidxFragmentWithoutOnCreate extends Fragment {

@NonNull private Object mOnCreateInitialisedField;
@NonNull private Object mOnCreateViewInitialisedField;
@NonNull private Object mOnAttachInitialisedField;

@Nullable
@Override
public View onCreateView(
@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
mOnCreateViewInitialisedField = new Object();
return super.onCreateView(inflater, container, savedInstanceState);
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
mOnAttachInitialisedField = new Object();
}
}
@@ -0,0 +1,26 @@
package com.uber.myapplication;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class AndroidxFragmentWithoutOnCreateView extends Fragment {

@NonNull private Object mOnCreateInitialisedField;
@NonNull private Object mOnCreateViewInitialisedField;
@NonNull private Object mOnAttachInitialisedField;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mOnCreateInitialisedField = new Object();
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
mOnAttachInitialisedField = new Object();
}
}
@@ -0,0 +1,32 @@
package com.uber.myapplication;

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

public class CoreFragmentWithoutOnAttach extends Fragment {

@NonNull private Object mOnCreateInitialisedField;
@NonNull private Object mOnCreateViewInitialisedField;
@NonNull private Object mOnAttachInitialisedField;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mOnCreateInitialisedField = new Object();
}

@Nullable
@Override
public View onCreateView(
@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
mOnCreateViewInitialisedField = new Object();
return super.onCreateView(inflater, container, savedInstanceState);
}
}
@@ -0,0 +1,33 @@
package com.uber.myapplication;

import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class CoreFragmentWithoutOnCreate extends Fragment {

@NonNull private Object mOnCreateInitialisedField;
@NonNull private Object mOnCreateViewInitialisedField;
@NonNull private Object mOnAttachInitialisedField;

@Nullable
@Override
public View onCreateView(
@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
mOnCreateViewInitialisedField = new Object();
return super.onCreateView(inflater, container, savedInstanceState);
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
mOnAttachInitialisedField = new Object();
}
}