001 package fj.test; 002 003 import fj.F; 004 import fj.P1; 005 import fj.data.List; 006 import fj.data.Option; 007 import static fj.data.Option.none; 008 import static fj.data.Option.some; 009 010 /** 011 * The result of evaluating a property. 012 * 013 * @version %build.number%<br> 014 * <ul> 015 * <li>$LastChangedRevision: 126 $</li> 016 * <li>$LastChangedDate: 2009-05-05 13:39:54 +1000 (Tue, 05 May 2009) $</li> 017 * <li>$LastChangedBy: tonymorris $</li> 018 * </ul> 019 */ 020 public final class Result { 021 private final Option<List<Arg<?>>> args; 022 private final R r; 023 private final Option<Throwable> t; 024 025 private enum R { 026 Unfalsified, Falsified, Proven, Exception, NoResult 027 } 028 029 private Result(final Option<List<Arg<?>>> args, final R r, final Option<Throwable> t) { 030 this.args = args; 031 this.r = r; 032 this.t = t; 033 } 034 035 /** 036 * Returns the potential arguments associated with this result. This will only have a value, if 037 * and only if {@link #noResult(Option) !noResult()} holds. 038 * 039 * @return The potential arguments associated with this result. 040 */ 041 public Option<List<Arg<?>>> args() { 042 return args; 043 } 044 045 /** 046 * Returns the potential exception associated with this result. This will only have a value if and 047 * only if this result is an exception result. 048 * 049 * @return The potential exception associated with this result. 050 */ 051 public Option<Throwable> exception() { 052 return t; 053 } 054 055 /** 056 * Returns <code>true</code> if this result is unfalsified; otherwise, <code>false</code>. 057 * 058 * @return <code>true</code> if this result is unfalsified; otherwise, <code>false</code>. 059 */ 060 public boolean isUnfalsified() { 061 return r == R.Unfalsified; 062 } 063 064 /** 065 * Returns <code>true</code> if this result is falsified; otherwise, <code>false</code>. 066 * 067 * @return <code>true</code> if this result is falsified; otherwise, <code>false</code>. 068 */ 069 public boolean isFalsified() { 070 return r == R.Falsified; 071 } 072 073 /** 074 * Returns <code>true</code> if this result is proven; otherwise, <code>false</code>. 075 * 076 * @return <code>true</code> if this result is proven; otherwise, <code>false</code>. 077 */ 078 public boolean isProven() { 079 return r == R.Proven; 080 } 081 082 /** 083 * Returns <code>true</code> if this result is an exception; otherwise, <code>false</code>. 084 * 085 * @return <code>true</code> if this result is an exception; otherwise, <code>false</code>. 086 */ 087 public boolean isException() { 088 return r == R.Exception; 089 } 090 091 /** 092 * Returns <code>true</code> if this result is no result; otherwise, <code>false</code>. 093 * 094 * @return <code>true</code> if this result is no result; otherwise, <code>false</code>. 095 */ 096 public boolean isNoResult() { 097 return r == R.NoResult; 098 } 099 100 /** 101 * Returns <code>true</code> if this result is falsified or an exception; otherwise, 102 * <code>false</code>. 103 * 104 * @return <code>true</code> if this result is falsified or an exception; otherwise, 105 * <code>false</code>. 106 */ 107 public boolean failed() { 108 return isFalsified() || isException(); 109 } 110 111 /** 112 * Returns <code>true</code> if this result is unfalsified or proven; otherwise, 113 * <code>false</code>. 114 * 115 * @return <code>true</code> if this result is unfalsified or proven; otherwise, 116 * <code>false</code>. 117 */ 118 public boolean passed() { 119 return isUnfalsified() || isProven(); 120 } 121 122 /** 123 * If this result is proven, alter it to be unfalsified with the same arguments; otherwise, return 124 * <code>this</code>. 125 * 126 * @return If this result is proven, alter it to be unfalsified with the same arguments; 127 * otherwise, return <code>this</code>. 128 */ 129 public Result provenAsUnfalsified() { 130 if(isProven()) 131 return unfalsified(args.some()); 132 else 133 return this; 134 } 135 136 /** 137 * Adds an argument to this result. 138 * 139 * @param a The argument to add. 140 * @return A result with the new argument. 141 */ 142 public Result addArg(final Arg<?> a) { 143 final F<Arg<?>, F<List<Arg<?>>, List<Arg<?>>>> cons = List.cons(); 144 return new Result(args.map(cons.f(a)), r, t); 145 } 146 147 /** 148 * Returns a potential result for this result. This will have a value if this result is 149 * {@link #noResult(Option) !noResult()}. 150 * 151 * @return A potential result for this result. 152 */ 153 public Option<Result> toOption() { 154 if(isNoResult()) 155 return none(); 156 else 157 return some(this); 158 } 159 160 /** 161 * Returns a result from the given potential result. 162 * 163 * @param r The potential result. 164 * @return The result that may be {@link #noResult() noResult()}. 165 */ 166 public static Result noResult(final Option<Result> r) { 167 return r.orSome(new P1<Result>() { 168 public Result _1() { 169 return noResult(); 170 } 171 }); 172 } 173 174 /** 175 * Returns a result representing no result. 176 * 177 * @return A result representing no result. 178 */ 179 public static Result noResult() { 180 return new Result(Option.<List<Arg<?>>>none(), R.NoResult, Option.<Throwable>none()); 181 } 182 183 /** 184 * Returns an unfalsified result. 185 * 186 * @param args The arguments used during the failure of falsification. 187 * @return An unfalsified result. 188 */ 189 public static Result unfalsified(final List<Arg<?>> args) { 190 return new Result(some(args), R.Unfalsified, Option.<Throwable>none()); 191 } 192 193 /** 194 * Returns a falsified result. 195 * 196 * @param args The arguments used during falsification. 197 * @return A falsified result. 198 */ 199 public static Result falsified(final List<Arg<?>> args) { 200 return new Result(some(args), R.Falsified, Option.<Throwable>none()); 201 } 202 203 /** 204 * Returns a proven result. 205 * 206 * @param args The arguments used during proof. 207 * @return A proven result. 208 */ 209 public static Result proven(final List<Arg<?>> args) { 210 return new Result(some(args), R.Proven, Option.<Throwable>none()); 211 } 212 213 /** 214 * Returns an exception result. 215 * 216 * @param args The arguments used when the exception occurred. 217 * @param t The exception that occurred. 218 * @return A exception result. 219 */ 220 public static Result exception(final List<Arg<?>> args, final Throwable t) { 221 return new Result(some(args), R.Exception, some(t)); 222 } 223 }