@Test public void subcomponentReleaseThenRestoreThenGcThenRelease() { assertBindingCallCounts(); component.childReleasableScope2Manager().releaseStrongReferences(); // release scope 4 assertBindingCallCounts(); // no change to scoped bindings component.childReleasableScope2Manager().restoreStrongReferences(); // restore scope 4 gcAndWaitUntilWeakReferencesCleared(ParentModule.class, ChildModule.class); // GC assertBindingCallCounts(); // no change to scoped bindings component.childReleasableScope2Manager().releaseStrongReferences(); // release scope 4 gcAndWaitUntilWeakReferencesCleared( ParentModule.class, ChildModule.class, ChildReleasableScope2.class); // GC childAsserts.expectedCallsForChildReleasableScope2Thing++; // expect scope 4 bindings again assertBindingCallCounts(); }
@Test public void setOfTypedReleasableReferenceManagers() { ListMultimap<Class<? extends Annotation>, Metadata1> managers = Multimaps.transformValues( Multimaps.index( component.typedReleasableReferenceManagers1(), new Function<TypedReleasableReferenceManager<?>, Class<? extends Annotation>>() { @Override public Class<? extends Annotation> apply( TypedReleasableReferenceManager<?> releasableReferenceManager) { return releasableReferenceManager.scope(); } }), new Function<TypedReleasableReferenceManager<Metadata1>, Metadata1>() { @Override public Metadata1 apply(TypedReleasableReferenceManager<Metadata1> manager) { return manager.metadata(); } }); assertThat(managers) .containsEntry(ParentReleasableScope2.class, metadata1("ParentReleasableScope2")); assertThat(managers) .containsEntry(ChildReleasableScope2.class, metadata1("ChildReleasableScope2.1")); assertThat(managers) .containsEntry(ChildReleasableScope3.class, metadata1("ChildReleasableScope3.1")); }
@Test public void releaseThenRestoreThenGcThenRelease() { assertBindingCallCounts(); component.parentReleasableScope2Manager().releaseStrongReferences(); // release scope 2 assertBindingCallCounts(); // no change to scoped bindings component.parentReleasableScope2Manager().restoreStrongReferences(); // restore scope 2 assertBindingCallCounts(); // no change to scoped bindings gcAndWaitUntilWeakReferencesCleared(ParentModule.class, ChildModule.class); // GC assertBindingCallCounts(); // no change to scoped bindings // Releasing again and GCing again means the binding is executed again. component.parentReleasableScope2Manager().releaseStrongReferences(); // release scope 2 assertBindingCallCounts(); // no change to scoped bindings gcAndWaitUntilWeakReferencesCleared( ParentModule.class, ChildModule.class, ParentReleasableScope2.class); // GC parentAsserts.expectedCallsForParentReleasableScope2Thing++; // expect scope 2 bindings again assertBindingCallCounts(); }
@Test public void releaseThenGc() { assertBindingCallCounts(); component.parentReleasableScope1Manager().releaseStrongReferences(); // release scope 1 assertBindingCallCounts(); // no change to scoped bindings gcAndWaitUntilWeakReferencesCleared( ParentModule.class, ChildModule.class, ParentReleasableScope1.class); // GC parentAsserts.expectedCallsForParentReleasableScope1Thing++; // expect scope 1 bindings again assertBindingCallCounts(); }
@Test public void releasableReferenceManagers() { ImmutableMap<Class<? extends Annotation>, ReleasableReferenceManager> managers = Maps.uniqueIndex( component.managers(), new Function<ReleasableReferenceManager, Class<? extends Annotation>>() { @Override public Class<? extends Annotation> apply( ReleasableReferenceManager releasableReferenceManager) { return releasableReferenceManager.scope(); } }); assertThat(managers) .containsEntry(ParentReleasableScope1.class, component.parentReleasableScope1Manager()); assertThat(managers) .containsEntry(ParentReleasableScope2.class, component.parentReleasableScope2Manager()); assertThat(managers) .containsEntry(ChildReleasableScope1.class, component.childReleasableScope1Manager()); assertThat(managers) .containsEntry(ChildReleasableScope2.class, component.childReleasableScope2Manager()); // Should contain a manager for ChildReleasableScope3 even though // @ForReleasableReferences(Scope5.class) isn't needed. assertThat(managers).containsKey(ChildReleasableScope3.class); }
@Test public void twoInstancesOfSameSubcomponent() { // Two instances of the same subcomponent. ChildAsserts child2Asserts = parentAsserts.newChildAsserts(); childAsserts.assertBindingCallCounts(); child2Asserts.assertBindingCallCounts(); component.childReleasableScope1Manager().releaseStrongReferences(); // release scope 3 childAsserts.assertBindingCallCounts(); // no change to scoped bindings in child 1 child2Asserts.assertBindingCallCounts(); // no change to scoped bindings in child 2 gcAndWaitUntilWeakReferencesCleared( ParentModule.class, ChildModule.class, ChildReleasableScope1.class); // GC childAsserts.expectedCallsForChildReleasableScope1Thing++; // expect scope 3 bindings again childAsserts.assertBindingCallCounts(); // when calling child.things() child2Asserts.expectedCallsForChildReleasableScope1Thing++; // expect scope 3 bindings yet again child2Asserts.assertBindingCallCounts(); // when calling child2.things() }
/** * Returns an object that can make assertions for the {@link Thing}s returned by {@link * Child#things()}. */ ChildAsserts newChildAsserts() { return new ChildAsserts(this, parent.child()); }