// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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 com.google.devtools.build.lib.util;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.google.common.testing.EqualsTester;
import java.util.function.Consumer;
import java.util.function.Function;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for {@link Either}.
 */
@RunWith(JUnit4.class)
public class EitherTest {
  @SuppressWarnings("unchecked")
  @Test
  public void leftConsume() {
    Either<Integer, String> underTest = Either.ofLeft(42);

    Consumer<Integer> mockIntegerConsumer = mock(Consumer.class);
    Consumer<String> mockStringConsumer = mock(Consumer.class);
    underTest.consume(mockIntegerConsumer, mockStringConsumer);

    verify(mockIntegerConsumer, times(1)).accept(eq(42));
    verify(mockStringConsumer, never()).accept(any());
  }

  @SuppressWarnings("unchecked")
  @Test
  public void leftMap() {
    Either<Integer, String> underTest = Either.ofLeft(42);

    Function<Integer, Boolean> mockIntegerFunction = mock(Function.class);
    Function<String, Boolean> mockStringFunction = mock(Function.class);
    when(mockIntegerFunction.apply(eq(42))).thenReturn(true);
    assertThat(underTest.map(mockIntegerFunction, mockStringFunction)).isTrue();

    verify(mockIntegerFunction, times(1)).apply(eq(42));
    verify(mockStringFunction, never()).apply(any());
  }

  @SuppressWarnings("unchecked")
  @Test
  public void rightConsume() {
    Either<Integer, String> underTest = Either.ofRight("cat");

    Consumer<Integer> mockIntegerConsumer = mock(Consumer.class);
    Consumer<String> mockStringConsumer = mock(Consumer.class);
    underTest.consume(mockIntegerConsumer, mockStringConsumer);

    verify(mockIntegerConsumer, never()).accept(any());
    verify(mockStringConsumer, times(1)).accept(eq("cat"));
  }

  @SuppressWarnings("unchecked")
  @Test
  public void rightMap() {
    Either<Integer, String> underTest = Either.ofRight("cat");

    Function<Integer, Boolean> mockIntegerFunction = mock(Function.class);
    Function<String, Boolean> mockStringFunction = mock(Function.class);
    when(mockStringFunction.apply(eq("cat"))).thenReturn(true);
    assertThat(underTest.map(mockIntegerFunction, mockStringFunction)).isTrue();

    verify(mockIntegerFunction, never()).apply(any());
    verify(mockStringFunction, times(1)).apply(eq("cat"));
  }

  @Test
  public void equalsAndHashCode() {
    new EqualsTester()
        .addEqualityGroup(Either.ofLeft(null), Either.ofLeft(null))
        .addEqualityGroup(Either.ofLeft(1), Either.ofLeft(1))
        .addEqualityGroup(Either.ofLeft(2), Either.ofLeft(2))
        .addEqualityGroup(Either.ofRight(1), Either.ofRight(1))
        .addEqualityGroup(Either.ofRight("cat"), Either.ofRight("cat"))
        .addEqualityGroup(Either.ofRight("dog"), Either.ofRight("dog"))
        .testEquals();
  }
}
