code: /*
   * Copyright (c) 2016-present, RxJava Contributors.
   *
   * 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.
   */
  
  package io.reactivex.rxjava3.single;
  
  import static org.junit.Assert.*;
  
  import java.io.IOException;
  import java.util.List;
  
  import org.junit.Test;
  
  import io.reactivex.rxjava3.core.*;
  import io.reactivex.rxjava3.disposables.Disposable;
  import io.reactivex.rxjava3.exceptions.*;
  import io.reactivex.rxjava3.functions.*;
  import io.reactivex.rxjava3.internal.functions.Functions;
  import io.reactivex.rxjava3.plugins.RxJavaPlugins;
  import io.reactivex.rxjava3.subjects.PublishSubject;
  import io.reactivex.rxjava3.testsupport.TestHelper;
  
  public class SingleSubscribeTest extends RxJavaTest {
  
      @Test
      public void consumer() {
          final Integer[] value = { null };
  
          Single.just(1).subscribe(new Consumer<Integer>() {
              @Override
              public void accept(Integer v) throws Exception {
                  value[0] = v;
              }
          });
  
          assertEquals((Integer)1, value[0]);
      }
  
      @Test
      public void biconsumer() {
          final Object[] value = { null, null };
  
          Single.just(1).subscribe(new BiConsumer<Integer, Throwable>() {
              @Override
              public void accept(Integer v, Throwable e) throws Exception {
                  value[0] = v;
                  value[1] = e;
              }
          });
  
          assertEquals(1, value[0]);
          assertNull(value[1]);
      }
  
      @Test
      public void biconsumerError() {
          final Object[] value = { null, null };
  
          TestException ex = new TestException();
  
          Single.error(ex).subscribe(new BiConsumer<Object, Throwable>() {
              @Override
              public void accept(Object v, Throwable e) throws Exception {
                  value[0] = v;
                  value[1] = e;
              }
          });
  
          assertNull(value[0]);
          assertEquals(ex, value[1]);
      }
  
      @Test
      public void subscribeThrows() {
          try {
              new Single<Integer>() {
                  @Override
                  protected void subscribeActual(SingleObserver<? super Integer> observer) {
                      throw new IllegalArgumentException();
                  }
              }.test();
          } catch (NullPointerException ex) {
              if (!(ex.getCause() instanceof IllegalArgumentException)) {
                  fail(ex.toString() + ": should have thrown NPE(IAE)");
              }
          }
      }
  
      @Test
      public void biConsumerDispose() {
          PublishSubject<Integer> ps = PublishSubject.create();
  
          Disposable d = ps.single(-99).subscribe(new BiConsumer<Object, Object>() {
              @Override
              public void accept(Object t1, Object t2) throws Exception {
  
              }
          });
  
          assertFalse(d.isDisposed());
  
          d.dispose();
  
          assertTrue(d.isDisposed());
  
          assertFalse(ps.hasObservers());
      }
  
      @Test
      public void consumerDispose() {
          PublishSubject<Integer> ps = PublishSubject.create();
  
          Disposable d = ps.single(-99).subscribe(Functions.<Integer>emptyConsumer());
  
          assertFalse(d.isDisposed());
  
          d.dispose();
  
          assertTrue(d.isDisposed());
  
          assertFalse(ps.hasObservers());
      }
  
      @Test
      public void consumerSuccessThrows() {
          List<Throwable> list = TestHelper.trackPluginErrors();
  
          try {
              Single.just(1).subscribe(new Consumer<Integer>() {
                  @Override
                  public void accept(Integer t) throws Exception {
                      throw new TestException();
                  }
              });
  
              TestHelper.assertUndeliverable(list, 0, TestException.class);
          } finally {
              RxJavaPlugins.reset();
          }
      }
  
      @Test
      public void consumerErrorThrows() {
          List<Throwable> list = TestHelper.trackPluginErrors();
  
          try {
              Single.<Integer>error(new TestException("Outer failure")).subscribe(
              Functions.<Integer>emptyConsumer(),
              new Consumer<Throwable>() {
                  @Override
                  public void accept(Throwable t) throws Exception {
                      throw new TestException("Inner failure");
                  }
              });
  
              TestHelper.assertError(list, 0, CompositeException.class);
              List<Throwable> cel = TestHelper.compositeList(list.get(0));
              TestHelper.assertError(cel, 0, TestException.class, "Outer failure");
              TestHelper.assertError(cel, 1, TestException.class, "Inner failure");
          } finally {
              RxJavaPlugins.reset();
          }
      }
  
      @Test
      public void biConsumerThrows() {
          List<Throwable> list = TestHelper.trackPluginErrors();
  
          try {
              Single.just(1).subscribe(new BiConsumer<Integer, Throwable>() {
                  @Override
                  public void accept(Integer t, Throwable e) throws Exception {
                      throw new TestException();
                  }
              });
  
              TestHelper.assertUndeliverable(list, 0, TestException.class);
          } finally {
              RxJavaPlugins.reset();
          }
      }
  
      @Test
      public void biConsumerErrorThrows() {
          List<Throwable> list = TestHelper.trackPluginErrors();
  
          try {
              Single.<Integer>error(new TestException("Outer failure")).subscribe(
              new BiConsumer<Integer, Throwable>() {
                  @Override
                  public void accept(Integer a, Throwable t) throws Exception {
                      throw new TestException("Inner failure");
                  }
              });
  
              TestHelper.assertError(list, 0, CompositeException.class);
              List<Throwable> cel = TestHelper.compositeList(list.get(0));
              TestHelper.assertError(cel, 0, TestException.class, "Outer failure");
              TestHelper.assertError(cel, 1, TestException.class, "Inner failure");
          } finally {
              RxJavaPlugins.reset();
          }
      }
  
      @Test
      public void methodTestNoCancel() {
          PublishSubject<Integer> ps = PublishSubject.create();
  
          ps.single(-99).test(false);
  
          assertTrue(ps.hasObservers());
      }
  
      @Test
      public void successIsDisposed() {
          assertTrue(Single.just(1).subscribe().isDisposed());
      }
  
      @Test
      public void errorIsDisposed() {
          assertTrue(Single.error(new TestException()).subscribe(Functions.emptyConsumer(), Functions.emptyConsumer()).isDisposed());
      }
  
      @Test
      public void biConsumerIsDisposedOnSuccess() {
          final Object[] result = { null, null };
  
          Disposable d = Single.just(1)
          .subscribe(new BiConsumer<Integer, Throwable>() {
              @Override
              public void accept(Integer t1, Throwable t2) throws Exception {
                  result[0] = t1;
                  result[1] = t2;
              }
          });
  
          assertTrue("Not disposed?!", d.isDisposed());
          assertEquals(1, result[0]);
          assertNull(result[1]);
      }
  
      @Test
      public void biConsumerIsDisposedOnError() {
          final Object[] result = { null, null };
  
          Disposable d = Single.<Integer>error(new IOException())
          .subscribe(new BiConsumer<Integer, Throwable>() {
              @Override
              public void accept(Integer t1, Throwable t2) throws Exception {
                  result[0] = t1;
                  result[1] = t2;
              }
          });
  
          assertTrue("Not disposed?!", d.isDisposed());
          assertNull(result[0]);
          assertTrue("" + result[1], result[1] instanceof IOException);
      }
  }
  