/** * Returns a Completable instance which manages a resource along * with a custom Completable instance while the subscription is active. * <p> * This overload disposes eagerly before the terminal event is emitted. * <dl> * <dt><b>Scheduler:</b></dt> * <dd>{@code using} does not operate by default on a particular {@link Scheduler}.</dd> * </dl> * @param <R> the resource type * @param resourceSupplier the supplier that returns a resource to be managed. * @param completableFunction the function that given a resource returns a Completable instance that will be subscribed to * @param disposer the consumer that disposes the resource created by the resource supplier * @return the new Completable instance */ @CheckReturnValue @SchedulerSupport(SchedulerSupport.NONE) public static <R> Completable using(Callable<R> resourceSupplier, Function<? super R, ? extends CompletableSource> completableFunction, Consumer<? super R> disposer) { return using(resourceSupplier, completableFunction, disposer, true); }
@Test(expected = NullPointerException.class) public void usingResourceSupplierNull() { Completable.using(null, new Function<Object, Completable>() { @Override public Completable apply(Object v) { return normal.completable; } }, new Consumer<Object>() { @Override public void accept(Object v) { } }); }
@Test(expected = NullPointerException.class) public void usingMapperNull() { Completable.using(new Callable<Object>() { @Override public Object call() { return 1; } }, null, new Consumer<Object>() { @Override public void accept(Object v) { } }); }
@Test(expected = NullPointerException.class) public void usingDisposeNull() { Completable.using(new Callable<Object>() { @Override public Object call() { return 1; } }, new Function<Object, Completable>() { @Override public Completable apply(Object v) { return normal.completable; } }, null); }
@Test(expected = TestException.class) public void usingResourceThrows() { Completable c = Completable.using(new Callable<Object>() { @Override public Object call() { throw new TestException(); } }, new Function<Object, Completable>() { @Override public Completable apply(Object v) { return normal.completable; } }, new Consumer<Object>() { @Override public void accept(Object v) { } }); c.blockingAwait(); }
@Test public void isDisposed() { TestHelper.checkDisposed(Completable.using(new Callable<Object>() { @Override public Object call() throws Exception { return 1; } }, new Function<Object, CompletableSource>() { @Override public CompletableSource apply(Object v) throws Exception { return Completable.never(); } }, new Consumer<Object>() { @Override public void accept(Object d) throws Exception { } }, false)); }
@Test(expected = TestException.class) public void usingMapperThrows() { Completable c = Completable.using(new Callable<Object>() { @Override public Object call() { return 1; } }, new Function<Object, Completable>() { @Override public Completable apply(Object v) { throw new TestException(); } }, new Consumer<Object>() { @Override public void accept(Object v) { } }); c.blockingAwait(); }
@Test(expected = NullPointerException.class) public void usingMapperReturnsNull() { Completable c = Completable.using(new Callable<Object>() { @Override public Object call() { return 1; } }, new Function<Object, Completable>() { @Override public Completable apply(Object v) { return null; } }, new Consumer<Object>() { @Override public void accept(Object v) { } }); c.blockingAwait(); }
@Test(expected = TestException.class) public void usingDisposerThrows() { Completable c = Completable.using(new Callable<Object>() { @Override public Object call() { return 1; } }, new Function<Object, Completable>() { @Override public Completable apply(Object v) { return normal.completable; } }, new Consumer<Object>() { @Override public void accept(Object v) { throw new TestException(); } }); c.blockingAwait(); }
@Test public void emptyEager() { Completable.using(new Callable<Object>() { @Override public Object call() throws Exception { return 1; } }, new Function<Object, CompletableSource>() { @Override public CompletableSource apply(Object v) throws Exception { return Completable.complete(); } }, new Consumer<Object>() { @Override public void accept(Object d) throws Exception { } }, true) .test() .assertResult(); }
@Test public void emptyNonEager() { Completable.using(new Callable<Object>() { @Override public Object call() throws Exception { return 1; } }, new Function<Object, CompletableSource>() { @Override public CompletableSource apply(Object v) throws Exception { return Completable.complete(); } }, new Consumer<Object>() { @Override public void accept(Object d) throws Exception { } }, false) .test() .assertResult(); }
@Test public void resourceSupplierThrows() { Completable.using(new Callable<Object>() { @Override public Object call() throws Exception { throw new TestException(); } }, new Function<Object, CompletableSource>() { @Override public CompletableSource apply(Object v) throws Exception { return Completable.complete(); } }, new Consumer<Object>() { @Override public void accept(Object d) throws Exception { } }) .test() .assertFailure(TestException.class); }
@Test public void errorEager() { Completable.using(new Callable<Object>() { @Override public Object call() throws Exception { return 1; } }, new Function<Object, CompletableSource>() { @Override public CompletableSource apply(Object v) throws Exception { return Completable.error(new TestException()); } }, new Consumer<Object>() { @Override public void accept(Object d) throws Exception { } }, true) .test() .assertFailure(TestException.class); }
@Test public void supplierCrashEager() { Completable.using(new Callable<Object>() { @Override public Object call() throws Exception { return 1; } }, new Function<Object, CompletableSource>() { @Override public CompletableSource apply(Object v) throws Exception { throw new TestException(); } }, new Consumer<Object>() { @Override public void accept(Object d) throws Exception { } }, true) .test() .assertFailure(TestException.class); }
@Test public void supplierCrashNonEager() { Completable.using(new Callable<Object>() { @Override public Object call() throws Exception { return 1; } }, new Function<Object, CompletableSource>() { @Override public CompletableSource apply(Object v) throws Exception { throw new TestException(); } }, new Consumer<Object>() { @Override public void accept(Object d) throws Exception { } }, false) .test() .assertFailure(TestException.class); }
@Test public void justDisposerCrashes() { Completable.using(new Callable<Object>() { @Override public Object call() throws Exception { return 1; } }, new Function<Object, CompletableSource>() { @Override public CompletableSource apply(Object v) throws Exception { return Completable.complete(); } }, new Consumer<Object>() { @Override public void accept(Object d) throws Exception { throw new TestException("Disposer"); } }, true) .test() .assertFailure(TestException.class); }
@Test public void errorNonEager() { Completable.using(new Callable<Object>() { @Override public Object call() throws Exception { return 1; } }, new Function<Object, CompletableSource>() { @Override public CompletableSource apply(Object v) throws Exception { return Completable.error(new TestException()); } }, new Consumer<Object>() { @Override public void accept(Object d) throws Exception { } }, false) .test() .assertFailure(TestException.class); }
@Test public void emptyDisposerCrashes() { Completable.using(new Callable<Object>() { @Override public Object call() throws Exception { return 1; } }, new Function<Object, CompletableSource>() { @Override public CompletableSource apply(Object v) throws Exception { return Completable.complete(); } }, new Consumer<Object>() { @Override public void accept(Object d) throws Exception { throw new TestException("Disposer"); } }, true) .test() .assertFailure(TestException.class); }
@Test public void dispose() { final int[] call = {0 }; TestObserver<Void> to = Completable.using(new Callable<Object>() { @Override public Object call() throws Exception { return 1; } }, new Function<Object, CompletableSource>() { @Override public CompletableSource apply(Object v) throws Exception { return Completable.never(); } }, new Consumer<Object>() { @Override public void accept(Object d) throws Exception { call[0]++; } }, false) .test(); to.cancel(); assertEquals(1, call[0]); }
@Test public void usingFactoryThrows() throws Exception { @SuppressWarnings("unchecked") Consumer<Integer> onDispose = mock(Consumer.class); TestObserver<Integer> ts = new TestObserver<Integer>(); Completable.using(new Callable<Integer>() { @Override public Integer call() { return 1; } }, new Function<Integer, Completable>() { @Override public Completable apply(Integer t) { throw new TestException(); } }, onDispose).subscribe(ts); verify(onDispose).accept(1); ts.assertNoValues(); ts.assertNotComplete(); ts.assertError(TestException.class); }