@Test
public void testActivityLeaks() {

  long baseClassActivityId = 1;
  long subClassActivityId = 2;
  long unrelatedClassId = 3;
  FakeCaptureObject capture = new FakeCaptureObject.Builder().build();
  // android.app.activity instance with mFinished field set to true and valid depth.
  FakeInstanceObject leakingBaseClassActivity =
    new FakeInstanceObject.Builder(capture, baseClassActivityId, ActivityFragmentLeakInstanceFilter.ACTIVTY_CLASS_NAME)
      .addField(ActivityFragmentLeakInstanceFilter.FINISHED_FIELD_NAME, ValueObject.ValueType.BOOLEAN, true)
      .setDepth(1)
      .build();
  // android.app.activity instance with no corresponding fields we can detect leaks from.
  FakeInstanceObject nonLeakingBaseClassActivity =
    new FakeInstanceObject.Builder(capture, baseClassActivityId, ActivityFragmentLeakInstanceFilter.ACTIVTY_CLASS_NAME)
      .addField("blah", ValueObject.ValueType.BOOLEAN, true)
      .build();
  // android.app.activity subclass instance with mDestroyed field set to true and valid depth.
  FakeInstanceObject leakingSubClassActivity =
    new FakeInstanceObject.Builder(capture, subClassActivityId, "my.activity.subclass")
      .setSuperClassId(baseClassActivityId)
      .addField(ActivityFragmentLeakInstanceFilter.DESTROYED_FIELD_NAME, ValueObject.ValueType.BOOLEAN, true)
      .setDepth(1)
      .build();
  // android.app.activity subclass instance with no corresponding fields we can detect leaks from.
  FakeInstanceObject nonLeakingSubClassActivity1 =
    new FakeInstanceObject.Builder(capture, subClassActivityId, "my.activity.subclass")
      .setSuperClassId(baseClassActivityId)
      .addField("blah", ValueObject.ValueType.BOOLEAN, true)
      .build();
  // android.app.activity subclass instance with mDestroyed field set to true but invalid depth (waiting to be gc'd instance)
  FakeInstanceObject nonLeakingSubClassActivity2 =
    new FakeInstanceObject.Builder(capture, subClassActivityId, "my.activity.subclass")
      .setSuperClassId(baseClassActivityId)
      .addField(ActivityFragmentLeakInstanceFilter.DESTROYED_FIELD_NAME, ValueObject.ValueType.BOOLEAN, true)
      .build();
  // unrelated class instance that does not belong to the android.app.activity hierarchy.
  FakeInstanceObject unrelatedClassInstance =
    new FakeInstanceObject.Builder(capture, unrelatedClassId, "my.other.class")
      .addField(ActivityFragmentLeakInstanceFilter.DESTROYED_FIELD_NAME, ValueObject.ValueType.BOOLEAN, true)
      .build();
  Set<InstanceObject> instances = ImmutableSet.of(leakingBaseClassActivity,
                                                  nonLeakingBaseClassActivity,
                                                  leakingSubClassActivity,
                                                  nonLeakingSubClassActivity1,
                                                  nonLeakingSubClassActivity2,
                                                  unrelatedClassInstance);
  ActivityFragmentLeakInstanceFilter filter = new ActivityFragmentLeakInstanceFilter();
  Set<InstanceObject> result = filter.filter(instances, capture.getClassDatabase());
  assertThat(result).containsExactly(leakingBaseClassActivity, leakingSubClassActivity);
}