Package com.google.common.testing.anotherpackage

Source Code of com.google.common.testing.anotherpackage.ForwardingWrapperTesterTest$ForwardingSub

/*
* Copyright (C) 2012 The Guava Authors
*
* 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.common.testing.anotherpackage;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.base.Equivalence;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.collect.Ordering;
import com.google.common.primitives.UnsignedInteger;
import com.google.common.primitives.UnsignedLong;
import com.google.common.testing.ForwardingWrapperTester;
import com.google.common.testing.NullPointerTester;

import junit.framework.TestCase;

import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

/**
* Tests for {@link ForwardingWrapperTester}. Live in a different package to detect reflection
* access issues, if any.
*
* @author Ben Yu
*/
public class ForwardingWrapperTesterTest extends TestCase {

  private final ForwardingWrapperTester tester = new ForwardingWrapperTester();

  public void testGoodForwarder() {
    tester.testForwarding(Arithmetic.class,
        new Function<Arithmetic, Arithmetic>() {
          @Override public Arithmetic apply(Arithmetic arithmetic) {
            return new ForwardingArithmetic(arithmetic);
          }
        });
    tester.testForwarding(ParameterTypesDifferent.class,
        new Function<ParameterTypesDifferent, ParameterTypesDifferent>() {
          @Override public ParameterTypesDifferent apply(ParameterTypesDifferent delegate) {
            return new ParameterTypesDifferentForwarder(delegate);
          }
        });
  }

  public void testVoidMethodForwarding() {
    tester.testForwarding(Runnable.class,
        new Function<Runnable, Runnable>() {
          @Override public Runnable apply(final Runnable runnable) {
            return new ForwardingRunnable(runnable);
          }
        });
  }

  public void testToStringForwarding() {
    tester.testForwarding(Runnable.class,
        new Function<Runnable, Runnable>() {
          @Override public Runnable apply(final Runnable runnable) {
            return new ForwardingRunnable(runnable) {
              @Override public String toString() {
                return runnable.toString();
              }
            };
          }
        });
  }

  public void testFailsToForwardToString() {
    assertFailure(Runnable.class, new Function<Runnable, Runnable>() {
      @Override public Runnable apply(final Runnable runnable) {
        return new ForwardingRunnable(runnable) {
          @Override public String toString() {
            return "";
          }
        };
      }
    }, "toString()");
  }

  public void testFailsToForwardHashCode() {
    tester.includingEquals();
    assertFailure(Runnable.class, new Function<Runnable, Runnable>() {
      @Override public Runnable apply(final Runnable runnable) {
        return new ForwardingRunnable(runnable) {
          @Override public boolean equals(Object o) {
            if (o instanceof ForwardingRunnable) {
              ForwardingRunnable that = (ForwardingRunnable) o;
              return runnable.equals(that.runnable);
            }
            return false;
          }
        };
      }
    }, "Runnable");
  }

  public void testEqualsAndHashCodeForwarded() {
    tester.includingEquals();
    tester.testForwarding(Runnable.class, new Function<Runnable, Runnable>() {
      @Override public Runnable apply(final Runnable runnable) {
        return new ForwardingRunnable(runnable) {
          @Override public boolean equals(Object o) {
            if (o instanceof ForwardingRunnable) {
              ForwardingRunnable that = (ForwardingRunnable) o;
              return runnable.equals(that.runnable);
            }
            return false;
          }
          @Override public int hashCode() {
            return runnable.hashCode();
          }
        };
      }
    });
  }

  public void testFailsToForwardEquals() {
    tester.includingEquals();
    assertFailure(Runnable.class, new Function<Runnable, Runnable>() {
      @Override public Runnable apply(final Runnable runnable) {
        return new ForwardingRunnable(runnable) {
          @Override public int hashCode() {
            return runnable.hashCode();
          }
        };
      }
    }, "Runnable");
  }

  public void testFailsToForward() {
    assertFailure(Runnable.class,
        new Function<Runnable, Runnable>() {
          @Override public Runnable apply(Runnable runnable) {
            return new ForwardingRunnable(runnable) {
              @Override public void run() {}
            };
          }
        }, "run()", "Failed to forward");
  }

  public void testRedundantForwarding() {
    assertFailure(Runnable.class,
        new Function<Runnable, Runnable>() {
          @Override public Runnable apply(final Runnable runnable) {
            return new Runnable() {
              @Override public void run() {
                runnable.run();
                runnable.run();
              }
            };
          }
        }, "run()", "invoked more than once");
  }

  public void testFailsToForwardParameters() {
    assertFailure(Adder.class, new Function<Adder, Adder>() {
      @Override public Adder apply(Adder adder) {
        return new FailsToForwardParameters(adder);
      }
    }, "add(", "Parameter #0");
  }

  public void testForwardsToTheWrongMethod() {
    assertFailure(Arithmetic.class, new Function<Arithmetic, Arithmetic>() {
      @Override public Arithmetic apply(Arithmetic adder) {
        return new ForwardsToTheWrongMethod(adder);
      }
    }, "minus");
  }

  public void testFailsToForwardReturnValue() {
    assertFailure(Adder.class, new Function<Adder, Adder>() {
      @Override public Adder apply(Adder adder) {
        return new FailsToForwardReturnValue(adder);
      }
    }, "add(", "Return value");
  }

  public void testFailsToPropagateException() {
    assertFailure(Adder.class, new Function<Adder, Adder>() {
      @Override public Adder apply(Adder adder) {
        return new FailsToPropagageException(adder);
      }
    }, "add(", "exception");
  }

  public void testNotInterfaceType() {
    try {
      new ForwardingWrapperTester().testForwarding(String.class, Functions.<String>identity());
      fail();
    } catch (IllegalArgumentException expected) {}
  }

  public void testNulls() {
    new NullPointerTester()
        .setDefault(Class.class, Runnable.class)
        .testAllPublicInstanceMethods(new ForwardingWrapperTester());
  }

  private <T> void assertFailure(
      Class<T> interfaceType, Function<T, ? extends T> wrapperFunction,
      String... expectedMessages) {
    try {
      tester.testForwarding(interfaceType, wrapperFunction);
    } catch (AssertionError expected) {
      for (String message : expectedMessages) {
        assertThat(expected.getMessage()).contains(message);
      }
      return;
    }
    fail("expected failure not reported");
  }

  private class ForwardingRunnable implements Runnable {

    private final Runnable runnable;

    ForwardingRunnable(Runnable runnable) {
      this.runnable = runnable;
    }

    @Override public void run() {
      runnable.run();
    }

    @Override public String toString() {
      return runnable.toString();
    }
  }

  private interface Adder {
    int add(int a, int b);
  }

  private static class ForwardingArithmetic implements Arithmetic {
    private final Arithmetic arithmetic;

    public ForwardingArithmetic(Arithmetic arithmetic) {
      this.arithmetic = arithmetic;
    }

    @Override public int add(int a, int b) {
      return arithmetic.add(a, b);
    }

    @Override public int minus(int a, int b) {
      return arithmetic.minus(a, b);
    }

    @Override public String toString() {
      return arithmetic.toString();
    }
  }

  private static class FailsToForwardParameters implements Adder {
    private final Adder adder;

    FailsToForwardParameters(Adder adder) {
      this.adder = adder;
    }

    @Override public int add(int a, int b) {
      return adder.add(b, a);
    }

    @Override public String toString() {
      return adder.toString();
    }
  }

  private static class FailsToForwardReturnValue implements Adder {
    private final Adder adder;

    FailsToForwardReturnValue(Adder adder) {
      this.adder = adder;
    }

    @Override public int add(int a, int b) {
      return adder.add(a, b) + 1;
    }

    @Override public String toString() {
      return adder.toString();
    }
  }

  private static class FailsToPropagageException implements Adder {
    private final Adder adder;

    FailsToPropagageException(Adder adder) {
      this.adder = adder;
    }

    @Override public int add(int a, int b) {
      try {
        return adder.add(a, b);
      } catch (Exception e) {
        // swallow!
        return 0;
      }
    }

    @Override public String toString() {
      return adder.toString();
    }
  }

  public interface Arithmetic extends Adder {
    int minus(int a, int b);
  }

  private static class ForwardsToTheWrongMethod implements Arithmetic {
    private final Arithmetic arithmetic;

    ForwardsToTheWrongMethod(Arithmetic arithmetic) {
      this.arithmetic = arithmetic;
    }

    @Override public int minus(int a, int b) { // bad!
      return arithmetic.add(b, a);
    }

    @Override public int add(int a, int b) {
      return arithmetic.add(b, a);
    }

    @Override public String toString() {
      return arithmetic.toString();
    }
  }

  private interface ParameterTypesDifferent {
    void foo(String s, Runnable r, Number n, Iterable<?> it, boolean b, Equivalence<String> eq,
        Exception e, InputStream in, Comparable<?> c, Ordering<Integer> ord,
        Charset charset, TimeUnit unit, Class<?> cls, Joiner joiner,
        Pattern pattern, UnsignedInteger ui, UnsignedLong ul, StringBuilder sb,
        Predicate<?> pred, Function<?, ?> func, Object obj);
  }

  private static class ParameterTypesDifferentForwarder implements ParameterTypesDifferent {
    private final ParameterTypesDifferent delegate;

    public ParameterTypesDifferentForwarder(ParameterTypesDifferent delegate) {
      this.delegate = delegate;
    }

    @Override public void foo(
        String s, Runnable r, Number n, Iterable<?> it, boolean b, Equivalence<String> eq,
        Exception e, InputStream in, Comparable<?> c, Ordering<Integer> ord,
        Charset charset, TimeUnit unit, Class<?> cls, Joiner joiner,
        Pattern pattern, UnsignedInteger ui, UnsignedLong ul, StringBuilder sb,
        Predicate<?> pred, Function<?, ?> func, Object obj) {
      delegate.foo(s,
          r, n, it, b, eq, e, in, c, ord, charset, unit, cls, joiner, pattern,
          ui, ul, sb, pred, func, obj);
    }

    @Override public String toString() {
      return delegate.toString();
    }
  }

  public void testCovariantReturn() {
    new ForwardingWrapperTester().testForwarding(Sub.class, new Function<Sub, Sub>() {
      @Override public Sub apply(Sub sub) {
        return new ForwardingSub(sub);
      }
    });
  }

  interface Base {
    CharSequence getId();
  }

  interface Sub extends Base {
    @Override String getId();
  }

  private static class ForwardingSub implements Sub {
    private final Sub delegate;

    ForwardingSub(Sub delegate) {
      this.delegate = delegate;
    }

    @Override public String getId() {
      return delegate.getId();
    }

    @Override public String toString() {
      return delegate.toString();
    }
  }

  private interface Equals {
    @Override boolean equals(Object obj);
    @Override int hashCode();
    @Override String toString();
  }

  private static class NoDelegateToEquals implements Equals {

    private static Function<Equals, Equals> WRAPPER = new Function<Equals, Equals>() {
      @Override public NoDelegateToEquals apply(Equals delegate) {
        return new NoDelegateToEquals(delegate);
      }
    };

    private final Equals delegate;

    NoDelegateToEquals(Equals delegate) {
      this.delegate = delegate;
    }

    @Override public String toString() {
      return delegate.toString();
    }
  }

  public void testExplicitEqualsAndHashCodeNotDelegatedByDefault() {
    new ForwardingWrapperTester()
        .testForwarding(Equals.class, NoDelegateToEquals.WRAPPER);
  }

  public void testExplicitEqualsAndHashCodeDelegatedWhenExplicitlyAsked() {
    try {
      new ForwardingWrapperTester()
          .includingEquals()
          .testForwarding(Equals.class, NoDelegateToEquals.WRAPPER);
    } catch (AssertionError expected) {
      return;
    }
    fail("Should have failed");
  }

  /**
   * An interface for the 2 ways that a chaining call might be defined.
   */
  private interface ChainingCalls {
    // A method that is defined to 'return this'
    ChainingCalls chainingCall();
    // A method that just happens to return a ChainingCalls object
    ChainingCalls nonChainingCall();
  }

  private static class ForwardingChainingCalls implements ChainingCalls {
    final ChainingCalls delegate;

    ForwardingChainingCalls(ChainingCalls delegate) {
      this.delegate = delegate;
    }

    @Override public ForwardingChainingCalls chainingCall() {
      delegate.chainingCall();
      return this;
    }

    @Override public ChainingCalls nonChainingCall() {
      return delegate.nonChainingCall();
    }

    @Override public String toString() {
      return delegate.toString();
    }
  }

  public void testChainingCalls() {
    tester.testForwarding(ChainingCalls.class,
        new Function<ChainingCalls, ChainingCalls>() {
          @Override public ChainingCalls apply(ChainingCalls delegate) {
            return new ForwardingChainingCalls(delegate);
          }
        });
  }
}
TOP

Related Classes of com.google.common.testing.anotherpackage.ForwardingWrapperTesterTest$ForwardingSub

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.