001    package fj.test;
002    
003    import fj.F;
004    import fj.pre.Show;
005    import static fj.pre.Show.anyShow;
006    import static fj.pre.Show.showS;
007    
008    /**
009     * An argument used in a property that may have undergone shrinking following falsification.
010     *
011     * @version %build.number%<br>
012     *          <ul>
013     *          <li>$LastChangedRevision: 122 $</li>
014     *          <li>$LastChangedDate: 2009-04-25 08:24:38 +1000 (Sat, 25 Apr 2009) $</li>
015     *          <li>$LastChangedBy: runarorama $</li>
016     *          </ul>
017     */
018    public final class Arg<T> {
019      private final T value;
020      private final int shrinks;
021    
022      private Arg(final T value, final int shrinks) {
023        this.value = value;
024        this.shrinks = shrinks;
025      }
026    
027      /**
028       * Construct a property argument with the given value and number of shrinks.
029       *
030       * @param value   The value to construct an argument with.
031       * @param shrinks The number of shrinks to construct an argument with.
032       * @return A new argument.
033       */
034      public static <T> Arg<T> arg(final T value, final int shrinks) {
035        return new Arg<T>(value, shrinks);
036      }
037    
038      /**
039       * Returns the argument's value.
040       *
041       * @return The argument's value.
042       */
043      public Object value() {
044        return value;
045      }
046    
047      /**
048       * Returns the argument's number of shrinks following falsification.
049       *
050       * @return The argument's number of shrinks following falsification.
051       */
052      public int shrinks() {
053        return shrinks;
054      }
055    
056      /**
057       * The rendering of an argument (uses {@link Object#toString()} for the argument value).
058       */
059      public static final Show<Arg<?>> argShow = showS(new F<Arg<?>, String>() {
060        public String f(final Arg<?> arg) {
061          return anyShow().showS(arg.value) +
062              (arg.shrinks > 0 ? " (" + arg.shrinks + " shrink" + (arg.shrinks == 1 ? "" : 's') + ')' : "");
063        }
064      });
065    }